在spark的优化过程中,shuffle的分区数量和数据倾斜问题一直是一个令人比较头疼的问题,自Spark 2.3.1版本后,自动设置shuffle Partition最新代码正式加入,但动态调整执行计划与处理数据倾斜并未同期并入该版本.
关于原理很多文章已经分析的差不多了,这里并不做提及,主要是记录相关参数及说明
1.自动设置 Shuffle Partition
-
spark.sql.adaptive.enabled=true
- 启用 Adaptive Execution 从而启用自动设置 Shuffle Reducer 这一特性 spark.sql.adaptive.shuffle.targetPostShuffleInputSize
- 可设置每个 Reducer 读取的目标数据量,其单位是字节,默认值为 64 MB。
2.动态调整执行计划
-
spark.sql.adaptive.enabled=true 与 spark.sql.adaptive.join.enabled=true
- 当这两个设置都为 true 时,开启 Adaptive Execution 的动态调整 Join 功能 spark.sql.adaptiveBroadcastJoinThreshold
- 设置了 SortMergeJoin 转 BroadcastJoin 的阈值。如果不设置该参数,该阈值与 spark.sql.autoBroadcastJoinThreshold 的值相等 spark.sql.adaptive.allowAdditionalShuffle
- Adaptive Execution 可以提供除SortMergeJoin 转 BroadcastJoin等以外其它 Join 优化策略。部分优化策略可能会需要增加 Shuffle。该参数就决定了是否允许为了优化 Join 而增加 Shuffle。其默认值为 false
3.自动处理数据倾斜
开启与调优自动处理数据倾斜的相关参数:
-
spark.sql.adaptive.skewedJoin.enabled=true
- 设置为 true 即可自动处理 Join 时数据倾斜 spark.sql.adaptive.skewedPartitionMaxSplits
- 控制处理一个倾斜 Partition 的 Task 个数上限,默认值为 5 spark.sql.adaptive.skewedPartitionRowCountThreshold
- 设置了一个 Partition 被视为倾斜 Partition 的行数下限,也即行数低于该值的 Partition 不会被当作倾斜 Partition 处理。其默认值为 10L * 1000 * 1000 即一千万 spark.sql.adaptive.skewedPartitionSizeThreshold
- 设置了一个 Partition 被视为倾斜 Partition 的大小下限,也即大小小于该值的 Partition 不会被视作倾斜 Partition。其默认值为 64 * 1024 * 1024 也即 64MB spark.sql.adaptive.skewedPartitionFactor
-
该参数设置了倾斜因子。如果一个 Partition 的大小大于 spark.sql.adaptive.skewedPartitionSizeThreshold 的同时大于各 Partition 大小中位数与该因子的乘积,或者行数大于
spark.sql.adaptive.skewedPartitionRowCountThreshold 的同时大于各 Partition 行数中位数与该因子的乘积,则它会被视为倾斜的 Partition