1 本质

在map和reduce两个阶段中,最容易出现数据倾斜的就是reduce阶段,因为map到reduce会经过shuffle阶段,在shuffle中默认会按照key进行hash,如果相同的key过多,那么hash的结果就是大量相同的key进入到同一个reduce中,导致数据倾斜。
在处理数据倾斜问题时,最终的目标是使map的输出数据更均匀的分布到reduce中去。数据倾斜的原因大多是人为的建表疏忽或业务逻辑可以规避的,所以我们在使用数据前一定要了解数据分布。

2 数据倾斜的表现

1)任务执行进度长时间卡在99%不动。
2)任务超时被杀掉,会返回一个 Code 143。

3 如何定位问题

查看yarn日志:
1)通过时间判断,如果某个 reduce 任务的运行时间比其他 reduce 时间长的多,则可能产生倾斜。
2)通过任务 Counter 判断(Counter 会记录每个 task 的统计信息),如果某个任务的输入记录数与其他任务相差较大,则可能产生倾斜。

定位SQL代码:
1)确定任务卡住的 stage,一般Hive默认的 jobname 名称会带上 stage 阶段。
2)通过执行计划和 stage 阶段,即可定位到 SQL 代码片段。

4 常见超时场景及解决方案

一般在join、group by、count distinct场景下容易产生数据倾斜。
容易产生数据倾斜的常见操作:

关键词 场景 结果
Join 其中一个表较小,但是key集中 分发到某一个或几个reduce上的数据远高于平均值
大表与大表,但是分桶的判断字段0值或空值过多 这些空值都由一个reduce处理,很慢
group by group by 维度过小,某个值的数量过多 处理此特殊值的reduce十分耗时
count distinct 某特殊值过多 处理此特殊值的reduce耗时

1)join

  • 空值引发的数据倾斜(最常见)。所有的null值都会被分配到一个reduce中,因为shuffle阶段的hash操作,只要key的hash结果是一样的,它们就会被分配到一个reduce中。解决方式:过滤掉空值或给空值赋随机数。
  • 不同类型的数据关联引发的数据倾斜。对于两个表join,表a中需要join的字段key为int,表b中key字段既有string类型也有int类型。当按照key进行两个表的join操作时,默认的Hash操作会按int型的id来进行分配,这样所有的string类型都被分配成同一个id,结果就是所有的string类型的字段进入到一个reduce中,引发数据倾斜。解决方式:统一数据类型。
  • 小表关联大表,key比较集中。解决方式:使用map join让小的维度表(1000条以下的记录条数) 先进内存。在map端完成reduce。Hive默认开启。hive.auto.convert.join=true 默认值为true,自动开启MAPJOIN优化。hive.mapjoin.smalltable.filesize=2500000 默认值为2500000(25M),通过配置该属性来确定使用该优化的表的大小,如果表的大小小于此值就会被加载进内存中。
  • 大表关联大表,解决方式:有空值过滤空值;提前裁剪过滤数据,缩小主键范围;按业务规则将大表切分成小表;单独调整reduce个数和内存。

2)group by、count distinct

  • 开启Map端聚合参数设置。数据倾斜时负载均衡,当选项设定为true,生成的查询计划会有两个MRJob。第一个MRJob 中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的GroupBy Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MRJob再根据预处理的数据结果按照GroupBy Key分布到Reduce中(这个过程可以保证相同的GroupBy Key被分布到同一个Reduce中),最后完成最终的聚合操作。
  • 对于很大的表,比如需要统计每个会员的总的交易额情况,采用上面的方法也不能跑出来。如果某个key的数据量特别大,数据都集中到某一个reduce Task去进行相关数据的处理,这就导致了数据倾斜问题。解决方案是首先采用局部聚合,即给key加上100以内的随机前缀,进行一次预聚合,然后对本次预聚合后的结果进行去掉随机前缀,进行一次数据的全局聚合。

面试指数:★★★★★
参考文档:
https://cloud.tencent.com/developer/article/1880491?from=article.detail.1353604
https://cloud.tencent.com/developer/article/1819620?from=article.detail.1353604
https://cloud.tencent.com/developer/article/1518308?from=article.detail.1353604
https://www.cnblogs.com/cstark/p/15100385.html