仅仅适用于聚合类的shuffle操作,适用范围相对较窄。如果是join类的shuffle操作,还得用其他的解决方案。
sparksql对于进行group by操作过程中产生的数据倾斜的处理。
使用sql来解决sparksql编程过程中出现的数据倾斜问题
以group by之后的dataskew为例来说明
dataskew:
什么是数据倾斜,表现有如何?
1. 数据分布不均匀,体现在,某一/几字段的数据特别多,只有在进行聚合计算的时候,数据才会进行重新分布。
2. 这个过程就是shuffle操作,shuffle操作的本质是相同key的数据汇聚到同一个计算节点上面进行聚合计算,这样
才会出现前面说的特点,某一个分区的数据可能会比其他的分区数据体积大得多,否则原始的数据本身相对是均匀。
表现一:
大多数task运行都非常快,但是个别task运行相对很慢,极端情况,持续执行到99%,就是不结束(mr和hive中常见)
表现二:
多数情况下,程序是正常运行的,但是某一天突然发生了OOM异常。
发生数据倾斜的原因:
就是数据分布不均匀,需要明确的是,数据分布不均匀,不一定会产生数据倾斜,但是只要有数据倾斜,则一定是由数据分布不均匀产生的。
如何会产生这个数据倾斜呢?我们来思考,在spark中作业的执行,不就是通过transformation来完成,可以将这些操作分为两种:
窄依赖的操作,一种是宽依赖操作。窄依赖操作都是在本地完成的,所以这种情况下就不可能产生数据倾斜的问题;宽依赖说白了也就是shuffle操作。
shuffle操作的实质是相同key的数据汇聚到同一个计算节点上面进行聚合计算,如果某一个key的数据比较多,就会导致对应节点上面的数据量
比正常的节点大得多,后续执行操作的时候就会有显著的差距------数据倾斜。
===>shuffle是发生数据倾斜的必要条件。
怎么解决呀?
原因就是相同key的数据太多,让着相同key的数据变少,就会减低或者消除数据倾斜,所以第一步,就需要找到这个数据倾斜的key(数据量最多的哪一个key),
怎么找到这个数据量最多key?不能全量进行计算,只能进行sample抽样,用样本去估计整体,样本空间可以执行wordcount—>
如何减少key——添加随机前缀,添加随机前缀之后进行聚合,聚合完毕之后要去掉随机前缀,进行第二次的聚合操作。当然这只是其中的一种处理方案(两阶段聚合)
参考美团技术文档
https://tech.meituan.com/2016/05/12/spark-tuning-pro.html
https://tech.meituan.com/2016/04/29/spark-tuning-basic.html
四个方面:
编程方面
资源调优(参数)
数据倾斜
shuffle