文章目录
数据倾斜是什么
总的来说,你集群运行时发现MR或者Hive卡在99%不动时,或者Spark运行时出现OOM异常(OutOfMemoryError),或者成功执行但就是耗时过久时,既要考虑是否出现了数据倾斜。数据倾斜就是某些key对应的数据分化不均,导致部分reduce处理数据量过大,以至于其他reduce都执行完了它还在运行。
查看web UI、日志文件:
看是否出现map和reduce任务执行时间过久,需要缓存数据集的操作消耗过多的内存资源
map端也是会出现数据倾斜的
MapReduce
减少Reduce数据倾斜
-
考虑map端使用Combine提前聚合部分数据
-
自定义分区,避免将过大数据量分发到某些reduce
MR默认分区方式是通过map输出的key的hash值来分发到某些reduce上的,数据分布均匀的话结果还好,但出现数据倾斜就是个问题
- 可以通过对原始数据进行抽样得到的结果集来预设分区边界值。TotalOrderPartitioner中的范围分区器可以通过预设的分区边界值进行分区。因此它也可以很好地用在矫正数据中的部分键的数据倾斜问题
- 像Hive那样,在出现数据倾斜的Key上加上随机前缀,先进行第一次局部聚合减少数据量。再去掉前缀进行第二次MapReduce全局聚合
-
涉及数据连接时,可以预习考虑在map端连接
- 数据大小倾斜的自定义策略
在map端或reduce端的数据大小倾斜都会对缓存造成较大的影响,乃至导致OutOfMemoryError异常。处理这种情况并不容易。可以参考以下方法。
- 设置
mapred.linerecordreader.maxlength
来限制RecordReader读取的最大长度。RecordReader在TextInputFormat和KeyValueTextInputFormat类中使用。默认长度没有上限。- 通过
org.apache.hadoop.contrib.utils.join
设置缓存的数据集的记录数上限。在reduce中默认的缓存记录数上限是100条。- 考虑使用有损数据结构压缩数据,如Bloom过滤器。
这里我不太理解,没有实际应用过吧。参考:https://www.cnblogs.com/datacloud/p/3601624.html
预判MapReduce中哪些key会出现数据倾斜
在reduce方法中加入记录map输出键的详细情况的功能。
在发现了倾斜数据的存在之后,就很有必要诊断造成数据倾斜的那些键。有一个简便方法就是在代码里实现追踪每个键的最大值。为了减少追踪量,可以设置数据量阀值,只追踪那些数据量大于阀值的键,并输出到日志中。实现代码如下。
public static final String MAX_VALUES = "skew.maxvalues";
private int maxValueThreshold;
@Override
public void configure