Spark数据倾斜解决方案
请列举Spark中数据倾斜(Data Skew)的常见原因和解决方案,包括调优参数和代码层面的优化。
回答
小字辈
数据倾斜表现: 某些Task处理大量数据而其他Task空闲,导致Job整体延迟高。
常见原因:
- Shuffle时Key分布不均匀(如null值过多、热点Key)
- 数据本身就有倾斜(如某些品类的订单量远大于其他品类)
- Join时大表Join大表且Join Key倾斜
解决方案:
1. 过滤或拆分异常Key:
- 过滤掉导致倾斜的Key(如null值)
- 将热点Key单独处理后再合并结果
2. 提高并行度(Salting / 加盐):
- 在Key上加随机前缀/suffix(1~N)打散
- 对
groupByKey/reduceByKey:先加盐聚合,再去盐聚合 - 示例:
rdd.map(kv => ((kv._1, Random.nextInt(10)), kv._2)).reduceByKey(_+_).map(kv => (kv._1._1, kv._2)).reduceByKey(_+_)
3. 调整并行度参数:
spark.sql.shuffle.partitions(默认200,根据数据量调大)spark.default.parallelism
4. 广播小表(MapJoin):
- 当Join的另一张表≤10MB时,使用
broadcast()强制广播 spark.sql.autoBroadcastJoinThreshold(默认10MB)
5. 两阶段聚合(Partial Aggregate):
- 第一次:随机前缀打散做局部聚合
- 第二次:去除前缀做全局聚合
6. 调整Shuffle相关参数:
spark.shuffle.file.buffer(默认32KB,增大减少磁盘I/O)spark.reducer.maxSizeInFlight(默认48MB,增大提升拉取效率)
最佳实践: 优先分析Shuffle UI看哪个Stage倾斜,针对性选择方案。