本文为您介绍产生数据倾斜的场景、产生原因及相应的处理措施。
问题现象
查看Logview时,发现有少数Fuxi Instance处理的数据量远远超过其他Fuxi Instance处理的数据量,从而导致少数Fuxi Instance的运行时长远远超过其他Fuxi Instance的平均运行时长,进而导致整个任务运行时间超长,造成任务延迟。例如,在历年双11的离线任务中,会遇到很多由于数据倾斜而导致的问题(主要是数据延迟),一方面是由于双11处理的数据量可能是平时的很多倍,另一方面业务上的“爆款”也在客观上一定程度地加大了数据倾斜发生的概率。
产生原因&处理措施
产生该问题的可能原因及对应的处理措施如下。
产生原因 | 描述 | 处理措施 |
---|---|---|
group by 倾斜
|
group by 的key 分布不均匀。
例如,在某一节日期间,某个店铺的单品PV量达4千万以上,店铺PV量达8千万以上,导致根据商品和店铺的PV量计算IPV时,发生数据倾斜。 |
在执行SQL语句前,设置防倾斜参数set odps.sql.groupby.skewindata=true; ,与SQL语句一起提交。
说明 当对常量执行
group by 操作时,设置该参数不会生效,需要您自行修改代码逻辑,避免对常量执行group by 操作。
|
join 倾斜
|
join on 的key 分布不均匀。
|
|
count distinct 倾斜
|
特殊值过多,常见于固定的特殊值比较多的场景,和join 中易产生倾斜的key 类似。
|
先过滤特殊值,在count 结果的基础上加上特殊值的个数。或根据具体场景进行具体分析。
例如,统计用户日购买UV、周购买UV和月购买UV:
|
错误使用动态分区 | 在不需要使用动态分区的场景,使用了动态分区。例如,某段代码示例如下:
在该示例中,没有必要使用动态分区,使用动态分区后,会启动Reduce Task,不仅浪费资源,还可能发生数据倾斜,应该使用固定分区,正确示例如下:
|
正确使用动态分区。如果必须使用动态分区,需要在执行SQL语句前,设置set odps.sql.reshuffle.dynamicpt=false; (默认值是False),与SQL语句一起提交。
|
未合理使用odps.sql.reducer.instances 参数
|
例如,某段代码示例如下:
在该示例中, |
从代码中删除odps.sql.reducer.instances 参数设置。
|