数据倾斜常见场景
- 表表关联
- 大小表关联
- 大表间关联(转化为大小表关联问题)
- 关联键含大量空值
- 关联键数据类型不一致
Group by
逻辑- count(distinct):
set hive.cbo.enable = true
1.大小表关联-mapjoin参数
|
|
在即席查询页面提交以上代码后,通过日志发现
在 525.23s 开始一直有一个节点长时间运行,此时其他所有节点都已经完成。推测发生了数据倾斜。
数据探源
探查相应表信息 DESC formatted 项目名.表名
发现表a数据量达30亿以上且为分区表,子查询结果b的数据量大10w+,表c为300+。
查看关联键信息
|
|
查到表a关联键的分布情况
00Axxx | 1204325436 |
---|---|
53xxx | 386342436 |
35xxx | 465 |
发现大小表关联时候关联键数量分布极其不均匀引起的,此时可以通过开启mapjoin参数进行优化。
- set hive.auto.convert.join = true
原理:由Reduce Join调整为Map Join,使其在Map端完成链接,省去Reduce端步骤。避免了大量同一个关联键落到了同一节点的可能性。
- 增加hint关键字
/* + mapjoin(表别名) */
原理:将关键字内的表强行加载入内存进行操作。
注意:不提倡将任何表都用hint关键字加载进内存,会造成内存溢出。
|
|
2.关联键含有空值-空值打散或过滤
空值的特性
- 空值字段作为关联键时,并不会参与链接
- 空值字段作为关联键时,拥有相同的key值,会被分发到同一任务节点
处理方式1:
过滤空值。提前将数据按关联键是否为空拆成两部分,关联后再将两部分数据进行合并。
如有需要可以开启并行parallel参数,再直接使用union all合并。
parallel参数:set hive.exc.parallel = true;
– 默认为false
处理方式2:
打散空值关联键,如图。
3.关联键数据类型不一致-cast()函数
强制转化数据类型后可能会因为精度丢失等原因引发数据倾斜。
一般建议统一转换成string类型进行关联。
4.Group by导致-skewindata参数
set hive.groupby.skewindata = true; --默认false
skewindata参数:
表现:由一个 Reducer 转变成两个Reducer。
第一个 Reducer 的作用:随机接收Map端输入的数据,达到负载均衡的目的。
第二个 Reducer 的作用:按照相同的 Groupby key,做最终聚合的操作。
开启参数前:
开启参数后:
在平时任务优化过程中发现,在执行速度上平均可以提升 80% 左右。