Spark sql数据倾斜
原因: 数据分布不均匀,某一个数据值 过多。
数据倾斜指的是,并行处理海量数据过程中,某个或者某些分区的数据显著多于其他分区,从而使得该部分的处理速度成为整个数据集处理的瓶颈。
方案: 把数据打散
-
抽数时发生数据倾斜
背景
oracle数据增量抽取: 抽取昨天更新的记录索引 last_modify_date
select * from table a
where last_modify_date >= to_date('${bizDate10}','YYYY-MM-DD HH24:MI:SS')
and last_modify_date < to_date('${bizDate10}+1','YYYY-MM-DD HH24:MI:SS')
报错:
Executor lost、OutOfMemoryError(OOM) 连接超时
优化1 : 拆成24小时
优化2 : 增加where 条件,mod(主键,7)=‘${a}’
select * from table a
where last_modify_date >= to_date('${bizDate10}','YYYY-MM-DD HH24:MI:SS')
and last_modify_date < to_date('${bizDate10}+1','YYYY-MM-DD HH24:MI:SS')
and mod(id,7)='${a}'
优化3 : 增加where 条件,ORA_hash(rowid,7)=‘${a}’
select * from table a
where last_modify_date >= to_date('${bizDate10}','YYYY-MM-DD HH24:MI:SS')
and last_modify_date < to_date('${bizDate10}+1','YYYY-MM-DD HH24:MI:SS')
and ORA_hash(rowid,7)=‘${a}’
-
复合索引 抽数时发生数据倾斜
背景
oracle数据增量抽取: 抽取昨天创建或者昨天更新的记录无索引
select * from table
where ( last_modify_date >= to_date('${bizDate10}','YYYY-MM-DD HH24:MI:SS')
and last_modify_date < to_date('${bizDate10}+1','YYYY-MM-DD HH24:MI:SS') )
or( create_date >= to_date('${bizDate10}','YYYY-MM-DD HH24:MI:SS')
and create_date < to_date('${bizDate10}+1','YYYY-MM-DD HH24:MI:SS'))
报错:
抽数经常超时、失效
优化1 : 创建2个索引,索引 last_modify_date+ 索引create_date
优化2 : 创建复合索引(last_modify_date,create_date)
select * from table
where ( last_modify_date >= to_date('${bizDate10}','YYYY-MM-DD HH24:MI:SS')
and last_modify_date < to_date('${bizDate10}+1','YYYY-MM-DD HH24:MI:SS') )
UNION
select * from table
WHERE (create_date >= to_date('${bizDate10}','YYYY-MM-DD HH24:MI:SS')
and create_date < to_date('${bizDate10}+1','YYYY-MM-DD HH24:MI:SS'))
- Left join 时发生数据倾斜
背景
SparkSql执行非常缓慢
select *
FROM Table_A a
LEFT JOIN Table_B b
on a.id (decimal,存在NULL值)= b.id (string,存在空值)
优化 :
select *
FROM Table_A a
LEFT JOIN (SELECT * FROM Table_B
WHERE CAST(id AS DECIMAL(18,0)) IS NOT NULL ) b
on a.id = b.id
- order by 容易导致数据倾斜,现象为 多跑几次能过
背景
偶尔进行重跑才能过
select *
from a
left join b
on a.id =b.id
order by a.update,b.update
order by排序原理: RangePartitioner会对RDD进行采样,比如1-100的数据
可能会被采样为0-50,51-100共2个分区
也可能会被采样为0-2 ,3-100 共2个分区--这种采样就会导致数据倾斜
优化 :
select *
from a
left join b
on a.id =b.id
--order by a.update,b.update
- 单表聚合时发生数据倾斜,现象为 执行报错
select data_DT,COUNT(0) from table a
group by data_DT
报错:
ErrorTime 连接超时
优化1 : 重新拼接成一个新字段 再group by
SELECT CONCAT(DATA_DT,'-',NEW) AS AA,COUNT(0)
FROM ( select DATA_DT,
ID%7 AS NEW
from table
) A
GROUP BY CONCAT(DATA_DT,'-',NEW)
- mapjoin ,大表 LEFT JOIN 小表(10MB),可优化为 Mapjoin
-
是否遇到过数据倾斜的问题,是如何解决的(某东)
你做项目的时候遇到过数据倾斜吗? 原因是什么,你是如何解决的答: 遇到过。原因是xx(原理结合生产案例,即可)
简历:通过xxx解决了数据倾斜的问题,由原来的需跑3次才能过,优化为3分钟跑过。
简历:通过xxx解决了数据倾斜的问题, 提高了ETL效率,由原来的凌晨3点结束SHDATA装载改为了1点.。
总结:小表 left join 小表
小表 left join 大表
大表 left join 小表(mapjoin)
大表 left join 大表(1.过滤key值,2.主表打散,从表扩容) -
在Spark开发中做过哪些优化(某宝)
-
谈谈对广播变量的理解,如何使用,解决了什么问题(某团)


规则: key.hashCode % reduce task 个数 = 该key应该放哪个partition
规则: 如图二 key.hashCode % 3 (即 reduce task 个数=3) =0 (即该key值放partition=0的分区中)


表象:
- Executor lost 、OOM、Shuffle过程频繁出现错误信息
–有可能是数据倾斜,也可能是资源没给够 - 单个Executor执行时间特别久,整体任务卡在某个阶段不能结束
–比如一共有1000个task,大多数task都跑完了,但某几个task迟迟不能跑完,这是比较明显的特征 - 正常运行的任务突然失败,大多数Task运行正常,个别Task运行缓慢或者发生OOM
–上线好几年了,以前跑的都很正常,但突然跑不通了

定位数据倾斜: 1、通过Spark Web UI查看报错的那个stage的各个task的运行时间以及分配的数据量,确认是否发生了数据倾斜
定位数据倾斜: 2、以shuffle类算子 为界限划分出了前后两个stage,从而定位到问题代码sql
思考:sql中哪些会发生shuffle

【秘籍1】优点:
【秘籍1】缺点:

【秘籍2】优点: 只适用于 关联条件 存在空值
【秘籍2】缺点:

【秘籍3】优点: 只适用于 大表Left join 小表
【秘籍3】缺点:

【秘籍4】优点: 调整Reduce并行度,非常方便
【秘籍4】缺点:不好确定到底需调整为多少个Reduce并行才可。

【秘籍5】优点: 只用于 单表聚合
【秘籍5】缺点:

【秘籍6】优点:
【秘籍6】缺点:
本文探讨了Spark SQL中数据倾斜的原因,如数据分布不均,以及在不同场景下如抽数、Left Join和单表聚合时发生倾斜的问题。提出多种解决策略,包括数据打散、调整Reduce并行度、MapJoin等,并分析了各种方法的优缺点。同时,通过Spark Web UI和SQL代码分析来定位数据倾斜,并给出了实际项目中优化ETL流程的案例。

1615

被折叠的 条评论
为什么被折叠?



