数据倾斜的产生和解决办法?
产生数据倾斜的原因
唯一值非常少,极少数值有非常多的记录值(唯一值少于几千)
唯一值比较多,这个字段的某些值有远远多于其他值的记录数,但是它的占比也小于百分之一或千分之一。
什么是数据倾斜
数据倾斜无非就是大量的相同 key 被 partition 分配到一个分区里,造成了’一个人累死,其他人闲死’的情况,这种情况是我们不能接受的,这也违背了并行计算的初衷,首先一个节点要承受着巨大的压力,而其他节点计算完毕后要一直等待这个忙碌的节点,也拖累了整体的计算时间,可以说效率是十分低下的。
数据倾斜的解决办法
增加 jvm 内存,这适用于第一种情况(唯一值非常少,极少数值有非常多的记录值(唯一值少于几千),这种情况下,往往只能通过硬件的手段来进行调优,增加 jvm 内存可以显著的提高运行效率。
增加 reduce 的个数,这适用于第二种情况(唯一值比较多,这个字段的某些值有远远多于其他值的记录数,但是它的占比也小于百分之一或千分之一),我们知道,这种情况下,最容易造成的结果就是大量相同 key 被 partition 到一个分区,从而一个 reduce 执行了大量的工作,而如果我们增加了 reduce 的个数,这种情况相对来说会减轻很多,毕竟计算的节点多了,就算工作量还是不均匀的,那也要小很多。
自定义分区,这需要用户自己继承 partition 类,指定分区策略,这种方式效果比较显著。
重新设计 key,有一种方案是在 map 阶段时给 key 加上一个随机数,有了随机数的 key 就不会被大量的分配到同一节点(小几率),待到 reduce 后再把随机数去掉即可。
使用 combinner 合并,combinner 是在 map 阶段,reduce 之前的一个中间阶段,在这个阶段可以选择性的把大量的相同 key 数据先进行一个合并,可以看做是 local reduce,然后再交给 reduce 来处理,这样做的好处很多,即减轻了 map 端向 reduce 端发送的数据量(减轻了网络带宽),也减轻了 map 端和 reduce 端中间的 shuffle 阶段的数据拉取数量(本地化磁盘 IO 速率),推荐使用这种方法。
了解更多大数据面试问题欢迎关注小编http://www.atguigu.com/专栏!
评论