Hadoop-Mapreduce数据倾斜与优化(小文件合并)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qichangjian/article/details/87949694

数据倾斜

1.产生原因:

Mapreduce程序在运行的时候,运行了大部分,但是还有部分reduce还在运行,甚至长时间运行,最终导致整个程序运行时间很长才结束。

造成这种现象的主要原因是

reduce程序处理的key的条数比其他key的条数大很多,这也就造成了分配到数据巨大的key的节点长时间运行。本质讲数据倾斜就是数据分布不均。

2.出现场景

不同的数据字段可能的数据倾斜一般有两种情况:

一种是唯一值非常少,极少数值有非常多的记录值(唯一值少于几千)
一种是唯一值比较多,这个字段的某些值有远远多于其他值的记录数,但是它的占比也小于百分之一或千分之一。

定位倾斜key方案
在reduce方法中加入记录map输出键的详细情况的功能。

3.解决方案

方式1:增加reduce 的jvm内存

既然reduce 本身的计算需要以合适的内存作为支持,在硬件环境容许的情况下,增加reduce 的内存大小显然有改善数据倾斜的可能,这种方式尤其适合数据分布第一种情况,单个值有大量记录, 这种值的所有纪录已经超过了分配给reduce 的内存,无论你怎么样分区这种情况都不会改变。

方式2: 增加reduce 个数

这个对于数据分布第二种情况有效,唯一值较多,单个唯一值的记录数不会超过分配给reduce 的内存. 如果发生了偶尔的数据倾斜情况,增加reduce 个数可以缓解偶然情况下的某些reduce 不小心分配了多个较多记录数的情况. 但是对于第一种数据分布无效。

方式3: 自定义partition

如果map输出键的单词来源于一本书。其中大部分必然是省略词(stopword: a,the,or )。那么就可以将自定义分区将这部分省略词发送给固定的一部分reduce实例。而将其他的都发送给剩余的reduce实例。

方式4:设定combiner

减少流向reduce的文件数量,从而减轻reduce数据倾斜。

Mapreduce的其他优化

1.合理处理maptask个数

Maptask个数太大:每个Maptask都要启动一个jvm进程,启动时间过长,效率低。
Maptask个数太小:负载不均衡,大量作业时,容易阻塞集群。
因此通常有两种手段来解决问题

  • 减少Maptask个数,通过合并小文件实现,主要针对数据源
  • 通过设置重用jvm进程的方式,减少MapReduce程序在启动和关闭jvm进程的时间:(set mapred.job.reuse.jvm.num.tasks=5) 表示map task 重用同一个jvm.

2.合理设置reduce task个数
 reducer 个数的设定极大影响执行效率。

3.小文件合并
小文件过多,会给hdfs带来压力,并且会影响处理效率,可以通过合并 Map 和 Reduce 的 结果文件来消除这样的影响。

1、小文件过多,会过多占用namenode的内存,并浪费block。 
	因为在hdfs 中,数据的元数据信息是保存在NameNode上的
	NameNode是要接收集群中所有的DataNode的心跳信息,来确定元数据的信息变化的
2、文件过小,寻道时间大于数据读写时间

如何合并小文件?
小文件的优化无非以下几种方式:
1、 在数据采集的时候,就将小文件或小批数据合成大文件再上传 HDFS
2、 在业务处理之前,在 HDFS 上使用 MapReduce 程序对小文件进行合并
3、 在 MapReduce 处理时,可采用 CombineFileInputFormat 提高效率

小文件合并实现:https://blog.csdn.net/luofazha2012/article/details/80904791

4.相关参数调优
每个 Map task ,reduce Task 最大重试次数等
参考Hadoop-Mapreduce参数调优

猜你喜欢

转载自blog.csdn.net/qichangjian/article/details/87949694