数据倾斜治理:Spark 和 Flink 都绕不开的问题

数据倾斜会让少数 Task 成为瓶颈,常见治理方式包括热 key 识别、加盐、两阶段聚合、广播 Join 和动态拆分。

数据倾斜治理:Spark 和 Flink 都绕不开的问题

分布式计算依赖并行。但如果数据分布不均,少数 Task 处理了绝大多数数据,整个作业就会被拖慢。

这就是数据倾斜。

Rendering diagram...

倾斜怎么产生

Group By 时,某个 key 特别大。

Join 时,某个 key 在两张表里都大量出现。

Kafka 分区时,某个 key 流量特别高。

这些都会导致单个 Task 或单个下游算子压力过大。

识别热 key

先统计 key 分布。

SELECT user_id, count(*) AS cnt
FROM events
GROUP BY user_id
ORDER BY cnt DESC
LIMIT 20;

如果 Top key 明显高于平均值,就要考虑倾斜治理。

加盐 Salting

对热 key 人为增加随机前缀,把一个大 key 拆成多个小 key。

SELECT concat(user_id, '_', cast(rand() * 10 as int)) AS salted_key, count(*)
FROM events
GROUP BY concat(user_id, '_', cast(rand() * 10 as int));

第一阶段按 salted key 聚合,第二阶段再去掉 salt 聚合。

广播 Join

小表 Join 大表时,广播小表可以避免大表 Shuffle。

但广播表不能太大,否则会压爆 Executor 内存。

Flink 里热 key 会导致某个并行子任务反压,Checkpoint 也可能变慢。

可以通过 key 拆分、局部聚合、异步 IO、调整并行度等方式缓解。

小结

数据倾斜不是参数问题,而是数据分布问题。先识别热 key,再选择加盐、两阶段聚合、广播 Join 或业务拆分。

参考链接