+-
Hadoop之性能测试与调优

Hadoop测试

集群搭建起来,是不是就万事大吉了呢?如果只是用来学习或者做做实验,貌似够了,但生产环境中还不够,因为我们还没有对集群进行测试,是不是能达到我们预期。

1.1写测试

测试写入100个128M的文件

hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.3-tests.jar TestDFSIO -write -nrFiles 100 -fileSize 128MB

1.2.读测试

测试读100个128的文件

hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.3-tests.jar TestDFSIO -read -nrFiles 100 -fileSize 128MB

1.3删除测试数据

测试数据必须删除,不能带到生产中

hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.3-tests.jar TestDFSIO -clean

1.4 用Sort评估MapReduce

1)使用RandomWriter来产生随机数,每个节点运行10个Map任务,每个Map产生大约1G大小的二进制随机数

hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar randomwriter random-data

2)执行sort

hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar sort random-data sorted-data

3)验证结果

hadoop jar /opt/module/hadoop-3.1.3/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.1.3-tests.jar testmapredsort -sortInput random-data -sortOutput sorted-data

哈哈,我的电脑不给力,没法直接演示,看来要升级了。
决定进入大数据坑的同学,电脑配置得高点,不然带不动。

2.Hadoop性能调优

集群测试,不符合预期,那就要进入性能调优了。

2.1 MpaReduce的优化

MapReduce执行效率的瓶颈在两个方面
1.计算机性能影响,像CPU、内存大小、磁盘、网络延迟。
2.IO方面的优化情况
1)数据倾斜问题
2)Map和Reduce的个数设置情况
3)Map耗时太长
4)小文件太多
5)Spill和Merge次数太多等等

我们对MapReduce的优化大致是六个方面
1)数据输入
2)Map阶段
3)Reduce阶段
4)IO传输
5)数据倾斜
6)参数调优

2.1.1 数据输入

例如合并小文件,我们都知道小文件会产生大量的MapTask,所以我们可以在执行MR任务前,先进行小文件的合并。

默认情况下TextInputformat对任务的切片机制是按文件规划切片,不管文件多小,都会有一个单独的切片,都会交给一个maptask,如果有大量的小文件,就会产生大量的maptask,处理效率及其低下
我们可以改用CombineTextInputFormat,解决输入端大量小文件的问题。

2.1.2 Map阶段

1.减少Spill次数,也就是溢写次数:通过调整io.sort.mb及sort.spill.percent参数值,增大触发Spill的内存上限,减少Spill次数,从而减少磁盘IO。

2.减少Merge次数:通过调整io.sort.factor参数,增大Merge的文件数目,减少Merge的次数,从而缩短MR处理时间。

3.Map之后,在不影响业务逻辑前提之下,可以先进行Combine,减少IO。

2.1.3 Reduce阶段

1.Map和Reduce个数的设置:两个不能设置太少,也不能太多。
太少,会导致Task等待,延长处理时间;
太多,会导致Map、Reduce任务间竞争资源,造成处理超时等错误。

2.Map、Reduce共存:调整slowstart.completedmaps参数,使Map运行到一定程度后,Reduce也开始运行,减少Reduce的等待时间。

3.规避使用Reduce:因为Reduce在用于连接数据集的时候将会产生大量的网络消耗。

2.1.4 IO传输

1)数据压缩
2)使用SequenceFile二进制文件

2.1.5 数据倾斜

什么是数据倾斜?
简单来说就是大量的相同key被partition分配到一个分区里,造成了'一个人累死,其他人闲死'的情况。

解决方法:
1)自定义分区,也就是Partition,指定分区策略
2)重新设计key,例如在map阶段给key加一个随机值,有了随机值的key就不会有大概率的机会被大量分到同一个节点上了,到了reduce阶段,在把随机值去掉。
3)使用Combine,Combinner是在map阶段,reduce之前的一个中间阶段,在这个阶段可以选择性的把大量的相同key数据先进行一个合并,可以看做是local reduce,然后再交给reduce来处理,这样做的好处很多,即减轻了map端向reduce端发送的数据量(减轻了网络带宽),也减轻了map端和reduce端中间的shuffle阶段的数据拉取数量(本地化磁盘IO速率)
解决方法也不止上面所述,具体也要根据实际情况来说。

2.1.6 调优参数

1)以下参数是在用户自己的MR应用程序中配置就可以生效(mapred-default.xml)

配置参数 参数说明 mapreduce.map.memory.mb 一个MapTask可使用的资源上限(单位:MB),默认为1024。如果MapTask实际使用的资源量超过该值,则会被强制杀死。 mapreduce.reduce.memory.mb 一个ReduceTask可使用的资源上限(单位:MB),默认为1024。如果ReduceTask实际使用的资源量超过该值,则会被强制杀死。 mapreduce.map.cpu.vcores 每个MapTask可使用的最多cpu core数目,默认值: 1 mapreduce.reduce.cpu.vcores 每个ReduceTask可使用的最多cpu core数目,默认值: 1 mapreduce.reduce.shuffle.parallelcopies 每个Reduce去Map中取数据的并行数。默认值是5 mapreduce.reduce.shuffle.merge.percent Buffer中的数据达到多少比例开始写入磁盘。默认值0.66 mapreduce.reduce.shuffle.input.buffer.percent Buffer大小占Reduce可用内存的比例。默认值0.7 mapreduce.reduce.input.buffer.percent 指定多少比例的内存用来存放Buffer中的数据,默认值是0.0

2)应该在YARN启动之前就配置在服务器的配置文件中才能生效(yarn-default.xml)

配置参数 参数说明 yarn.scheduler.minimum-allocation-mb 给应用程序Container分配的最小内存,默认值:1024 yarn.scheduler.maximum-allocation-mb 给应用程序Container分配的最大内存,默认值:8192 yarn.scheduler.minimum-allocation-vcores 每个Container申请的最小CPU核数,默认值:1 yarn.scheduler.maximum-allocation-vcores 每个Container申请的最大CPU核数,默认值:32 yarn.nodemanager.resource.memory-mb 给Containers分配的最大物理内存,默认值:8192

3)Shuffle性能优化的关键参数,应在YARN启动之前就配置好(mapred-default.xml)

配置参数 参数说明 mapreduce.task.io.sort.mb Shuffle的环形缓冲区大小,默认100m mapreduce.map.sort.spill.percent 环形缓冲区溢出的阈值,默认80%

4)容错相关参数(MapReduce性能优化)

配置参数 参数说明 mapreduce.map.maxattempts 每个Map Task最大重试次数,一旦重试参数超过该值,则认为Map Task运行失败,默认值:4。 mapreduce.reduce.maxattempts 每个Reduce Task最大重试次数,一旦重试参数超过该值,则认为Map Task运行失败,默认值:4。 mapreduce.task.timeout Task超时时间,经常需要设置的一个参数,该参数表达的意思为:如果一个Task在一定时间内没有任何进入,即不会读取新的数据,也没有输出数据,则认为该Task处于Block状态,可能是卡住了,也许永远会卡住,为了防止因为用户程序永远Block住不退出,则强制设置了一个该超时时间(单位毫秒),默认是600000。如果你的程序对每条输入数据的处理时间过长(比如会访问数据库,通过网络拉取数据等),建议将该参数调大,该参数过小常出现的错误提示是“AttemptID:attempt_14267829456721_123456_m_000224_0 Timed out after 300 secsContainer killed by the ApplicationMaster.”。

2.2 小文件的问题

为什么HDFS怕小文件呢?
因为HDFS上每个文件都要在NameNode建立一个索引,这个索引大小约150byte,当大量小文件时,就会产生很多的索引文件,但内存是有限制的,另外索引文件过大也会使得索引查询效率降低。

所以小文件问题,在生产环境中一定要引起注意的问题。
解决方式就是减少小文件产生或者对小文件合并,具体有以下几种方式:
1)在数据采集的时候,就将小文件或小批数据合成大文件再上传HDFS。
2)在业务处理之前,在HDFS上使用MapReduce程序对小文件进行合并。
3)在MapReduce处理时,可采用CombineTextInputFormat提高效率。