数据倾斜问题
表现:某个ReduceTask一直卡在99% 或 100%
产生原因:ReduceTask的数据分配不均衡,导致一个ReduceTask的负载比其他的高很多,于是进度卡住
根本原因:分区的时候使用Hash分区,优点是相同的key会进入同一个reduce处理,但这样可能会导致数据倾斜
那为什么不用随机或者轮寻分区器呢:
-因为shuffle的最终目的是分组,如果相同key不进入同一个分区,怎么实现全局分组呢
数据倾斜的场景,即平常哪些代码会造成数据倾斜
group by /count【distinct】:分组
join【Reduce Join】
解决方案:
通用方案:调整Reduce的个数:
适用于多个key集中在某个reduce导致的数据倾斜
当一个key数据过多时没办法解决,因为就算加了reduce个数也不会被分到多个reduce
分组导致的数据倾斜解决方案:
1.开启Combiner,减少进入Reduce数据量,来避免数据倾斜(map端聚合) : hive.map.aggr=true
适用于分组造成的数据倾斜,在map端进行一次聚合
- 随机分区:刚才说了,shuffle的目的时分组,随机分区并不能实现分组,所有这个方法需要走两次MapReduce,第一次实现随机分区,第二次实现最终分组聚合,虽然解决了数据倾斜,但多了一个MapReduce
—方式一:开启参数:hive.groupby.skewindata=true,开启后,底层会自动走两个MapReduce
—方式二:手动指定:distribute by rand():将数据写入随机的分区中,避免数据倾斜,适合于这一步的结果并不是最终结果,一定后续还有程序会对当前数据的进行处理
join导致的数据倾斜解决方案:
reducejoin的原理:把join表的关联字段作为key,进行Hash分区,这样相同key的数据进入同一分区,才可以分组、拼接,形成新的数据
为什么不能用map端聚合解决join的数据倾斜问题呢?
join是会形成笛卡尔积的,但不是所有笛卡尔积都是没用的,如果使用map端聚合,相同关联字段的多条数据聚合在一起,join后会丢失数据,比本来join后有8条数据,map端聚合后再join就剩下1条了
为什么不能用随机分区呢?
随机分区以后相同关联字段的数据进入了不同分区,如何join呢
1.尽量避免走Reduce Join
Map Join:尽量将不需要参加Join的数据过滤,将大表转换为小表
如果两张大表没办法变成小表,可以构建分桶Bucket Map Join
2.skewjoin:避免数据倾斜的Reduce Join过程【限制:只适用与内连接】
优化核心思想:谓词下推,处理数据之前先进行过滤
具体措施:1.能在where中过滤,就不要在having中过滤
2.做join或者分排序的时候提前过滤掉无用的数据
版权归原作者 三个石头有水喝 所有, 如有侵权,请联系我们删除。