spark结合hive数据倾斜的几种解决方案

数据倾斜表现:

有的task执行很快,有的很慢或者内存溢出

定位数据倾斜的位置:

用client模式提交,观察log

解决方案

1、在hive etl时进行数据聚合,把key相同的数据聚合成一条数据,这样就可能不用shuffle了,从而解决数据倾斜。

当没办法对key进行聚合时也可以选择其它粒度聚合,比如数据中包含了几个城市,几个职业,可以选择合适的粒度聚合。

2、过滤导致倾斜的key

如果业务允许某几个key的数据可以丢弃,那么对于有两个key对应10万条数据,而其它key都是几十条,那么就可以过滤那两个key。

3、提高ruduce并行度从而使key更分散,从而有可能解决数据倾斜。

4、双重聚合法(针对非join,如groupByKey,reduceByKey)

1、在每个key前加上一个随机数和一个分隔符比如:"2_",那么key对应的数量就比较均匀了,然后做第一次reduce。

2、把第一次聚合得到的RDD的前缀(x_)去掉,再进行一次聚合即可。

5、reduce join转map join

就是把一个RDD的信息放到broadcast变量中,作为另一个RDD的map操作变量和它做配对操作(没有join操作,一个RDD进行mapToPair操作,另一个RDD变成广播list传入然后变map)

reduce join转换为map join,适合在什么样的情况下,可以来使用?

如果两个RDD要进行join,其中一个RDD是比较小的。一个RDD是100万数据,一个RDD是1万数据。(一个RDD是1亿数据,一个RDD是100万数据)

其中一个RDD必须是比较小的,broadcast出去那个小RDD的数据以后,就会在每个executor的block manager中都驻留一份。

要确保你的内存足够存放那个小RDD中的数据

这种方式下,根本不会发生shuffle操作,肯定也不会发生数据倾斜;从根本上杜绝了join操作可能导致的数据倾斜的问题;

对于join中有数据倾斜的情况,大家尽量第一时间先考虑这种方式,效果非常好;如果某个RDD比较小的情况下。

对于join这种操作,不光是考虑数据倾斜的问题;即使是没有数据倾斜问题,也完全可以优先考虑,用我们讲的这种高级的reduce join转map join的技术,

不要用普通的join,去通过shuffle,进行数据的join;完全可以通过简单的map,使用map join的方式,牺牲一点内存资源;在可行的情况下,优先这么使用。

不走shuffle,直接走map,是不是性能也会高很多?这是肯定的。

6、可以先从要join的一个RDD中抽取10%的数据并从中得到数量最多的那个key,然后从两个RDD中过滤出这个key的数据,得当两个RDD,rdd1和rdd2,然后对两个RDD中的key加随机

前缀,如果rdd2的数据只有一个,那么就用for多生成几个,然后俩个RDD做join,然后对那些非特殊的RDD进行join,然后union两个结果。

什么时候不适用呢?

如果一个RDD中,导致数据倾斜的key,特别多;那么此时,最好还是不要这样了;

7、扩容方式

就是把一个RDD扩大n倍(越大越好,只要内存足够),这个RDD的每个数据的key前都分别加x_,共n个,对于另一个RDD的每一个key前加随机前缀,

然后对两个RDD做join。

适用场合

两个RDD很大,且影响数据倾斜的数据有多个

局限

内存消耗

猜你喜欢

转载自qianjiangbing.iteye.com/blog/2328660