Hadoop调优总结

1. 管理员角度主要在四方面进行调优
    (1) 硬件选择、
    (2)操作系统参数调优、
    (3)jvm参数调优、
    (4)hadoop参数调优。
2.操作系统调优
(1).增大同时打开的文件描述符合网络连接上限。
管理员在启动hadoop集群时,应使用ulimit命令将允许同时打开的文件描述符数目上限增大至一个合适的值,同时调整内核参数
net.core.somaxconn至一个足够大的值。此外,hadoop rpc采用了epoll作为高并发库,如果你使用的linux内核版本在2.6.28以上,你需要适当调整epoll的文件描述符上限。
(2).关闭swap分区
在linux中,如果一个进程的内存空间不足,那么,它会将内存中的部分数据暂时写到磁盘上,当需要时,再将磁盘上的数据动态置换到内存中,通常而言,这种行为会大大降低进程的执行效率。在mr分布式计算环境中,用户完全可以通过控制每个作业处理的数据量和每个任务运行过程中用到的各种缓冲区大小,避免使用swap分区。(可调整/etc/sysct1.conf文件中的vm.swappiness参数)
(3).设置合理的预读取缓冲区大小
磁盘I/O性能的发展远远滞后于CPU和内存,因而成为现代计算机系统的一个主要瓶颈。预读可以有效地减少磁盘的寻道次数和应用程序的
I/O等待时间,是改进磁盘读I/O性能的重要优化手段之一。管理员可使用linux命令blockdev设置预读取缓冲区的大小,以提高hadoop
中大文件顺序读的性能。当然,也可以只为Hadoop系统本身增加预读缓冲区大小。。
(4).文件系统选择与配置
Hadoop的I/O性能很大程度上依赖于Linux本地文件系统的读写性能。Linux中有多种文件系统可供选择,比如ext3和ext4,不同的文件系统性能有一定的差别。如果公司内部有自主研发的更高效的文件爱你系统,也鼓励使用。
(5).I/O调度器选择
主流的Linux发行版自带了很多可供选择的I/O调度器。在数据密集型应用中,不同的I/O调度器性能表现差别较大,管理员可根据自己的应用特点启用最合适的I/O调度器,具体可参考AMD的白皮书《Hadoop Performance Tuning Guide》
3.优化Hadoop
(1)  从应用程序角度进行优化。
由于mapreduce是迭代逐行解析数据文件的,怎样在迭代的情况下,编写高效率的应用程序,是一种优化思路。

(2)  对Hadoop参数进行调优。
当前hadoop系统有190多个配置参数,怎样调整这些参数,使hadoop作业运行尽可能的快,也是一种优化思路。

(3) 从系统实现角度进行优化。
这种优化难度是最大的,它是从hadoop实现机制角度,发现当前Hadoop设计和实现上的缺点,然后进行源码级地修改。该方法虽难度大,但往往效果明显。
4.     从应用程序角度进行优化
(1) 避免不必要的reduce任务

如果要处理的数据是排序且已经分区的,或者对于一份数据, 需要多次处理, 可以先排序分区;然后自定义InputSplit, 将单个分区作为单个mapred的输入;在map中处理数据, Reducer设置为空。

这样, 既重用了已有的 “排序”, 也避免了多余的reduce任务。

(2)外部文件引入

有些应用程序要使用外部文件,如字典,配置文件等,这些文件需要在所有task之间共享,可以放到分布式缓存DistributedCache中(或直接采用-files选项,机制相同)。

更多的这方面的优化方法,还需要在实践中不断积累。

(3) 为job添加一个Combiner

为job添加一个combiner可以大大减少shuffle阶段从map task拷贝给远程reduce task的数据量。一般而言,combiner与reducer相同。

(4) 根据处理数据特征使用最适合和简洁的Writable类型

Text对象使用起来很方便,但它在由数值转换到文本或是由UTF8字符串转换到文本时都是低效的,且会消耗大量的CPU时间。当处理那些非文本的数据时,可以使用二进制的Writable类型,如IntWritable, FloatWritable等。二进制writable好处:避免文件转换的消耗;使map task中间结果占用更少的空间。

(5) 重用Writable类型

很多MapReduce用户常犯的一个错误是,在一个map/reduce方法中为每个输出都创建Writable对象。例如,你的Wordcout mapper方法可能这样写:
(6) 使用StringBuffer而不是String

当需要对字符串进行操作时,使用StringBuffer而不是String,String是read-only的,如果对它进行修改,会产生临时对象,而StringBuffer是可修改的,不会产生临时对象。

(7)调试

最重要,也是最基本的,是要掌握MapReduce程序调试方法,跟踪程序的瓶颈。具体可参考:

http://www.cloudera.com/blog/2009/12/7-tips-for-improving-mapreduce-performance/ 

5.HIVE数据倾斜

(1). 万能膏药:hive.groupby.skewindata=true
(2). 大小表关联:将key相对分散,并且数据量小的表放在join的左边,这样可以有效减少内存溢出错误发生的几率;再进一步,可以使用map join让小的维度表(1000条以下的记录条数)先迚内存。在map端完成reduce.
(3). 大表和大表关联:把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。
(4). count distinct大量相同特殊值:count distinct时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。

猜你喜欢

转载自x10232.iteye.com/blog/2230161