数据倾斜
问题
什么是数据倾斜?如何排查和解决?
答案
什么是数据倾斜
数据倾斜是指在分布式计算中,某些节点处理的数据量远大于其他节点,导致整体任务被最慢的节点拖慢。
常见原因
| 原因 | 示例 |
|---|---|
| Key 分布不均 | GROUP BY city,北京占 60% |
| NULL 值集中 | user_id IS NULL 占大量 |
| 大表 JOIN 大表 | 热门商品的订单量远大于其他 |
| COUNT DISTINCT | 某些分区的去重量异常大 |
解决方案
| 方案 | 原理 | 适用 |
|---|---|---|
| 过滤 NULL | 先过滤空值单独处理 | NULL 导致的倾斜 |
| Salting Key | 给热点 Key 添加随机前缀分散 | GROUP BY 倾斜 |
| Broadcast Join | 小表广播,避免 Shuffle | 大小表 JOIN |
| 两阶段聚合 | 先局部聚合 + 再全局聚合 | 大量重复 Key |
| 调参 | 开启 Hive/Spark 的倾斜优化参数 | 通用 |
-- 方案 1:过滤 NULL 单独处理
SELECT city, COUNT(*) FROM orders WHERE city IS NOT NULL GROUP BY city
UNION ALL
SELECT 'NULL_CITY', COUNT(*) FROM orders WHERE city IS NULL;
-- 方案 2:Salting Key(Spark SQL)
-- 第一步:加盐打散
SELECT CONCAT(user_id, '_', FLOOR(RAND() * 10)) AS salted_key, amount
FROM orders;
-- 第二步:先按 salted_key 聚合,再去掉盐聚合
-- 方案 3:Broadcast Join(Spark)
-- spark.sql.autoBroadcastJoinThreshold = 10485760 (10MB)
SELECT /*+ BROADCAST(dim) */ *
FROM fact_orders f JOIN dim_products dim ON f.product_id = dim.product_id;
数据倾斜是大数据面试高频题
面试中问到"任务跑得慢",首先想到数据倾斜。排查步骤:
- 看 Spark UI / Flink 的 Task 执行时间分布
- 定位哪个 Stage 慢
- 查看 Key 的分布(是否有热点)
- 选择对应的解决方案
常见面试问题
Q1: 如何快速判断是否有数据倾斜?
答案:
- 看 Spark UI 的 Task 时间:大部分秒级完成,个别分钟级 → 倾斜
- 看 Shuffle Read 的数据量分布
- SQL 排查热点 Key:
SELECT key, COUNT(*) FROM table GROUP BY key ORDER BY 2 DESC LIMIT 10
Q2: Broadcast Join 有什么限制?
答案:
- 小表要足够小(默认 10MB,可调大但不宜超过 1GB)
- 小表会被广播到每个 Executor 的内存
- 不适用于两个大表的 JOIN