(一)硬件层面优化
(1)多网卡
1)多网卡绑定为一个IP地址
2)可以增加网络带宽、形成网卡的冗余阵列
•分担负载,网络流量可以被同时分配到多个网卡上,在同样的流量下,每块网卡负载降低,在流量 增加的时候,由于多块网卡协同作用能够提高网络流量
•提高通信可靠性:当其中一块网卡发生故障时,另一块网卡可以继续工作,传输不间断
3)在Linux上可以通过配置文件的方式将两个物理网卡绑定在一起
(2)多磁盘
(3)超线程
超线程技术就是在一颗CPU同时执行多个程序而共同分享一颗CPU内的资源,理论上要像两颗CPU一样在 同一时间执行两个线程
采用超线程时可在同一时间里,应用程序可以使用芯片的不同部分。虽然单线程芯片每秒钟能够处理成千上 万条指令,但是在任一时刻只能够对一条指令进行操作。而超线程技术可以使芯片同时进行多线程处理,使芯 片性能得到提升。 虽然采用超线程技术能同时执行两个线程,但它并不象两个真正的CPU那样,每个CPU都 具有独立的资源。当两个线程都同时需要某一个资源时,其中一个要暂时停止,并让出资源,直到这些资源闲 置后才能继续。因此超线程的性能并不等于两颗CPU的性能。
进入BIOS里,找Hyper-Threading项,改为enabled就是开启超线程
(4)双电源
在条件允许的情况下推荐双电源
(二)操作系统层面优化
(1)文件句柄和进程数限制
1)/etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
2)RHEL6 下还需要修改/etc/security/limits.d/90-nproc.conf
* soft nproc 65535
* hard nproc 65535
(2)禁用电源管理( 省电模式)
vi /etc/grub.conf 增加如下参数
intel_idle.max_cstate=0
processor.max_cstate=0
(3)禁用selinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config setenforce 0
注意: setenforce是Linux的selinux防火墙配置命令 执行setenforce 0 表示关闭selinux防火墙。 setenforce命令是单词set(设置)和enforce(执行)连写,另一个命令getenforce可查看selinux 的状态。
(4)禁用防火墙
检查防火墙自启动设置: chkconfig --list | grep tables
关闭防火墙自启动命令: chkconfig iptables off; chkconfig ip6tables off
关闭防火墙命令: service iptables stop; service ip6tables stop
(5)noatime
vi /etc/fstab
/dev/vdb1 /data/vdb1 ext4 defaults,noatime 0 0
(6)禁用 redhat_transparent_hugepage
关闭 redhat_transparent_hugepage 参数
echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled
/etc/rc.local文件增加如下系统启动检查 文件增加如下系统启动检查
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
(三)JVM层面优化
(1)使用稳定的
使用最新稳定版jdk
(2)合理的堆内存大小
(3)jstat
jstat -gcutil 12122 1000
(4)jvisualvm+jstatd
(5)远程 debug(jdwp)
Java远程调试的原理是两个VM之间通过debug协议进行通信,然后以达到远程调试的目的。两者之间可以通过 socket进行通信。
首先被debug程序的虚拟机在启动时要开启debug模式,启动debug监听程序。jdwp是Java Debug Wire Protocol 的缩写。
java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n zhc_application
这是jdk1.7版本之前的方法,1.7之后可以这样用:
java -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n zhc_application
(四)Hadoop层面优化
(1)机架感知
1)背景
①机器多,跨机架
②机架内网络带宽远大于机架间带宽
2)特点
① hadoop对机架的感知并非是自适应的,需要人为指定
②启动时,将rack的信息保存在内存中
③尽量将所有的副本分布到不同的rack中
3)副本存放策略
由于hadoop的HDFS对数据文件的分布式存放是按照分块block存储,每个block会有多个副本(默认为3),并且 为了数据的安全和高效,所以hadoop默认对3个副本的存放策略为:
第一个block副本放在和client所在的node里(如果client不在集群范围内,则这第一个node是随机选取的)。
第二个副本放置在与第一个节点不同的机架中的node中(随机选择)。
第三个副本放置在与第二个副本所在节点同一机架的另一个节点上
如果还有更多的副本就随机放在集群的node里。
4)机架感知原理
基于主机的位置分配块
管理员提供了一个脚本,它告诉Hadoop的一个节点是在哪个机架
脚本的输入参数:主机ip或主机名
脚本输出:机架id
可以使用shell或python脚本
hadoop启用机架感知,增加配置项
< property>
< name>topology.script.file.name< /name>
< value>/path/to/RackAware.py< /value>
< /property
5)机架感知 python 实现
#!/usr/bin/python
#-*-coding:UTF-8 -*-
import sys
rack = {"ocdata01":"rack1",
"ocdata02":"rack1",
"ocdata03":"rack1",
"ocdata04":"rack2",
"ocdata05":"rack2",
"ocdata06":"rack2",
"10.1.253.91":"rack1",
"10.1.253.92":"rack1",
"10.1.253.93":"rack1",
"10.1.253.94":"rack2",
"10.1.253.95":"rack2",
"10.1.253.96":"rack2",
}
if __name__=="__main__":
print "/" + rack.get(sys.argv[1],"rack0")
6)机架感知 shell脚本实现
#!/bin/bash
conf="ocdata01:10.1.253.91:/rack1\nocdata02:10.1.253.92:
/rack1\nocdata03:10.1.253.93:/rack1\nocdata04:10.1.253.9
4:/rack2\nocdata05:10.1.253.95:/rack2\nocdata06:10.1.253.
96:/rack2\n"
ip=$1
rack=`echo -e $conf|grep $ip|awk -F':' '{print $3}'`
echo $rack
(2)充分利用多磁盘的优势
Hdfs数据目录配置多个目录
mr中间目录要配置多个,分散IO压力
yarn.nodemanager.local-dirs
/hdfs/data1/local,/hdfs/data2/local
yarn.nodemanager.log-dirs
/hdfs/data1/yarn/userlogs,/hdfs/data2/yarn/userlogs
(3)使用合理的压缩算法
中间结果要压缩
mapreduce.compress.map.output设置为true
mapreduce.map.output.compression.codec设置为相应的codec,默认
org.apache.hadoop.io.compress.DefaultCodec。
~/app/hadoop-2.6.0-cdh5.4.5/bin/yarn jar analysis-1.0-SNAPSHOT.jar pv -
Dmapreduce.compress.map.output=true -
Dmapreduce.map.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec
/input /outpu10
(10)
(4)调优过程
• 监控工具
安装一个nmon(sudo yum install nmon)
后台运行nmon -f -s 5 -c 100
• 准备一批数据,尽量多一点,尽量贴近生产
• 没调优之前跑一次,观察资源占用情况并作记录
• 调优一次,跑一次看看效果
• 不断反复直到最优
(5)其他
• 要有有效的监控和调试工具
• 根据节点情况调整task的并行度
• 使用Combiner
• 重用Writable类型
(五)应用层面优化
• 避免小文件
• pool机制
• 其他