数据倾斜
跳到导航
跳到搜索
数据倾斜:在并行进行数据处理的时候,由于单个 partition 的数据显著多余其他部分,分布不均匀,导致大量数据集中分布到少数计算节点上,使得该部分的处理速度远低于平均计算速度,成为整个数据集处理的瓶颈,从而影响整体计算性能。
原因
- 对于 join 过程来说,如果出项较多的 key 值为空或异常的记录,或 key 值分布不均匀,就容易出现数据倾斜
- 对于 group by 过程来说,如果某一个 key 值有特别的多的记录,其它 key 值的记录比较少,也容易出项数据倾斜
方案
Join
- 如果是由于 key 值为空或为异常记录,且这些记录不能被过滤掉的情况下,可以考虑给 key 赋一个随机值,将这些值分散到不同的 reduce 进行处理
- 如果是一个大表和一个小表 join 的话,可以考虑使用 mapjoin 来避免数据倾斜
Group
方法一:
set hive.groupby.skewindata=true
只针对单列有效。数据倾斜时负载均衡,当选项设定为 true,生成的查询计划会有两个 MRJob。第一个 MRJob 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MRJob 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。
方法二:
set hive.map.aggr=true;
在 map 中会做部分聚集操作,效率更高但需要更多的内存。开启 map 之后使用 combiner,这样基本上是对各记录比较同质的数据效果比较好,相反,则没有什么意义。通用的做法是设置下面两个参数:
set hive.groupby.mapaggr.checkinterval = 100000 # (默认)执行聚合的条数 set hive.map.aggr.hash.min.reduction=0.5 # (默认)
- 如果 hash 表的容量与输入行数之比超过这个数,那么 map 端的 hash 聚合将被关闭,默认是 0.5
- 设置为 1 可以保证 hash 聚合永不被关闭