一:Hive的ETL优化
方案应用场景:
hive表数据倾斜,表中数据本身分布不均匀,频繁使用Spark对某个Hive表执行操作
方案实现思路:
1.通过Hive 的ETL预先对数据按照key进行聚合,或和其他表预先进行join
2.生成预处理后的Hive表(数据源已经不是原来的Hive表了)
3.数据已经进行了预聚合或预join,所以spark作业不用进行shuffle操作
原理:
把数据倾斜的发生提前到了Hive ETL中,避免Spark程序发生数据倾斜而已,数据本身就可能分布不均匀,Hive ETL中进行join等shuffle操作也可能出现数据倾斜,属于治标不治本。
优点:
简捷,高效,完全规避了数据倾斜,spark作业性能也能够大幅度提升
缺点:
只是解决了spark作业的数据倾斜,Hive ETL还会发生数据倾斜,所以未能从根本上解决数据倾斜问题
share:
1.在一些Java系统与Spark集成项目时,会出现Java代码频繁调用Spark作业的场景,而且对Spark作业的执行性能要求很高,就比较适合使用这种方案。
2.将数据倾斜提前到上游的Hive ETL,每天仅执行一次,只有那一次是比较慢的,而之后每次Java调用Spark作业时,执行速度都会很快,能够提供更好的用户体验。
二:对少数导致数据倾斜的Key进行过滤
方案应用场景:
导致数据倾斜的Key只有少数几个,并且对计算本身影响不大。
方案实现思路:
从业务角度判断出数据量比较大的几个Key,在对spark作业执行和计算影响不重要的前提下,过滤掉这几个Key,如果需要每次作业执行时,动态判定哪些key的数据量最多然后再进行过滤,那么可以使用sample算子对RDD进行采样,然后计算出每个key的数量,取数据量最多的key过滤掉即可。
原理:
将要发生数据倾斜的Key过滤之后,这些key就不会参与执行与计算,当然也就不会发生数据倾斜了
优点:
实现简单,可以完全规避掉数据倾斜,效果简单粗暴,有效
缺点:
大部分发生数据倾斜的数据都比较有用,所以使用场景很少
share:
在做流量数据分析的时候,遇到过此场景,比如就是因为127.0.0.1等等这种数据不需要参与计算,结果导致进行了大量的shuffle算子操作。出现各种异常
三:提高shuffle并行度
方案应用场景:
处理数据倾斜最简单的一种方案,解决数据倾斜问题建议优先考虑这种解决方案
方案实现思路:
1.在对RDD执行shuffle算子时,传参,比如reduceByKey(1000),该参数就设置了这个shuffle算子执行时shuffle read task的数量。
2.对于Spark SQL中的shuffle类语句,比如group by、join等,需要设置一个参数,即spark.sql.shuffle.partitions,该参数代表了shuffle read task的并行度,该值默认是200,对于很多场景来说都有点过小。
原理:
增加shuffle read task的数量,可以让每个task处理更少的数据
优点:
实现起来比较简单,可以有效缓解和减轻数据倾斜的影响。
缺点:
未能从根本上解决数据倾斜问题,只是缓解了数据倾斜的影响
share:
尝试解决的一种简单方案,数据量绝对大时还时没法解决的,可以和其他方案结合起来用
四:局部聚合+全局聚合
方案应用场景:
对RDD执行reduceByKey等聚合类shuffle算子或者在Spark SQL中使用group by语句进行分组聚合时