记录大数据面试历程
数据倾斜
大数据岗位 ,数据倾斜面试必问的一个问题。
一、数据倾斜的表现与原因
-
表现
-
某个或某几个Task执行时间过长,其他Task快速完成。
-
Spark/MapReduce作业卡在某个阶段(如
reduce
阶段),日志显示少数Task处理大量数据。 -
资源利用率不均衡(如CPU、内存集中在某些节点)。
-
-
常见场景
-
Key分布不均:如某些Key对应的数据量极大(如用户ID为空的记录、热点事件)。
-
数据分区策略不合理:Hash分区时Key冲突,或Range分区时范围划分不均衡。
-
业务逻辑导致倾斜:如大表Join小表时小表广播失败,或笛卡尔积操作。
-
二、检测数据倾斜的方法
-
日志分析
-
查看任务执行时间分布(如Spark UI的Stage详情)。
-
检查Shuffle读写数据量(如
Shuffle Read/Write Records
)。
-
-
抽样统计
-
对Key进行采样,统计Top N高频Key(如用
countByKey
或sample
)。
-
-
监控工具
-
使用Ganglia、Prometheus等监控节点资源负载。
-
三、通用解决方案
1. 预处理:过滤或隔离倾斜数据
-
过滤异常Key:直接删除无意义的倾斜Key(如空值、测试数据)。
-
分离热点数据:将高频Key单独处理,与非倾斜数据合并结果。
-- 示例:将热点用户的行为日志单独处理
SELECT * FROM logs WHERE user_id = 'hot_user' -- 单独处理
UNION ALL
SELECT * FROM logs WHERE user_id != 'hot_user' -- 正常处理
2. 调整Key分布
增加随机前缀(Salting):对Key添加随机数,分散数据到不同分区。
# Spark示例:对倾斜Key添加随机前缀
skewed_rdd = rdd.map(lambda x: (x[0] + "_" + str(random.randint(0, 9)), x[1]))
两阶段聚合:
-
对Key加随机前缀,局部聚合;
-
去掉前缀,全局聚合。
3. 优化Shuffle过程
-
提高并行度:增加分区数(如
spark.sql.shuffle.partitions=2000
)。 -
使用Combiner:在Map端预聚合(如ReduceByKey替代GroupByKey)。
-
广播小表:在Join时,将小表广播到所有Executor,避免Shuffle。
4. 使用特定框架优化
-
Spark AQE(Adaptive Query Execution):
Spark 3.0+ 支持动态合并倾斜分区(spark.sql.adaptive.skewJoin.enabled=true
)。 -
Flink KeyBy前加盐:类似Spark的随机前缀方法。
-
Hive参数调优:
set hive.map.aggr=true;
(Map端聚合)
set hive.groupby.skewindata=true;
(生成两个MR Job分散负载)。
四、场景化解决方案
场景1:Join操作倾斜
方案1:将小表广播
-- Spark SQL广播Join
SELECT /*+ BROADCAST(small_table) */ *
FROM big_table JOIN small_table ON big_table.key = small_table.key;
方案2:拆分倾斜Key
若大表和大表Join且某些Key倾斜:
-
提取倾斜Key单独Join;
-
非倾斜Key正常Join;
-
合并结果
场景2:Group By/Aggregation倾斜
方案:两阶段聚合(加盐与去盐
-- 第一阶段:对Key加随机后缀,局部聚合
SELECT key || '_' || suffix AS salted_key, SUM(value)
FROM table
GROUP BY key || '_' || suffix;-- 第二阶段:去除后缀,全局聚合
SELECT REPLACE(salted_key, '_*', '') AS key, SUM(sum_value)
FROM temp_table
GROUP BY REPLACE(salted_key, '_*', '');
场景3:数据源倾斜
方案:调整文件分区
-
写入数据时使用合理的分区策略(如按时间+哈希混合分区)。
-
对小文件合并,对大文件拆分。
五、预防数据倾斜的设计原则
-
合理选择分区键:避免选择基数低或分布不均的字段。
-
数据预分析:ETL阶段提前统计Key分布,识别潜在倾斜。
-
动态调整:利用AQE(自适应查询执行)等自动化优化机制。
面试回答示例
问题:如何处理Spark作业中的数据倾斜?
回答:
-
定位倾斜:通过Spark UI查看Stage中Task的数据量分布,找到倾斜的Key。
-
过滤无效数据:如删除空Key或异常值。
-
调整Key分布:对倾斜Key加随机前缀,分两阶段聚合。
-
优化Shuffle:提高
shuffle.partitions
,使用广播Join。 -
框架特性:开启Spark AQE,自动合并倾斜分区。
-
举例:在最近的项目中,某用户行为日志的UserID存在热点,通过加盐将原本集中在1个分区的数据分散到10个分区,作业时间从2小时缩短至15分钟。
数据倾斜调优
更多信息请参 阿里云帮助中心
数据倾斜调优_云原生大数据计算服务 MaxCompute(MaxCompute)-阿里云帮助中心