Spark面试经典系列之数据倾斜解决方案的“银弹”是什么?

本节我们对Spark数据倾斜解决方案进行回顾和总结:

1、   数据倾斜运行的症状和危害。如果发行数据倾斜,往往发现作业任务运行特别

缓慢,出现OOM内存溢出等现象。

2、   如果两个RDD进行操作,其中1个RDD数据不是那么多,我们把这个RDD的

数据以广播变量的形式包裹起来,广播给整个Cluster集群。这样就可以和另外一个RDD进行map操作。

3、   如果两个RDD进行Join操作,如果1个RDD有严重的数据倾斜。我们可以通

过采样的方式发现RDD1中有严重的数据倾斜的Key,然后将原来一个RDD1拆分成RDD11(产生倾斜Key的数据)和RDD12(不产生倾斜Key的数据),把RDD11、RDD12分别和RDD2进行Join操作,然后把分别Join操作后的结果进行Union操作。此外,倾斜的Key也可加上随机数处理。

4、   如果两个RDD数据特别多,而且倾斜的key成千上万个,我们可以考虑进行数

据扩容,将其中一个RDD的数据进行扩容N倍,另外一个RDD的每条数据都打上一个n以内的随机前缀,最后将两个处理后的RDD进行join。

5、   从并行度的角度考虑:

·          初级级别的并行度解决方案:例如reduceByKey在第二个参数中指定并行度来

改善数据倾斜;

·          进阶级别的并行度解决方案:以reduceByKey为例,在原有数据分片的基础上

加上随机数前缀,进行reduceByKey,然后进行map操作,去掉随机数前缀,再次进行reduceByKey,这种方式很有效。

我们讲解了数据倾斜这么多的解决方式,几乎涵盖了数据倾斜方方面面的内容。无论是改变并行度、Key值加上随机数、进行广播变量、数据扩容……等等,都是类似的解决思路,这些方案是否足以解决数据倾斜的问题?作为数据倾斜解决方案的“银弹”,我们需穷尽一下解决方案,能不能将数据倾斜消灭在问题产生以前?Spark是处理数据的,在处理数据的过程中产生了数据倾斜,由于数据的特征导致了数据倾斜。如果在数据来源的根源上解决了数据倾斜,Spark本身就不会面临数据倾斜的问题。在实际生产环境中,不能单一的考虑Spark本身的问题。

逃离Spark技术本身之外来如何解决数据倾斜的问题?

之所以会有这样的想法,是因为从结果上来看,数据倾斜的产生来自于数据和数据的处理技术,之前我们都是从数据的技术处理层面考虑如何解决数据倾斜,我们现在需要回到数据的层面去解决数据倾斜的问题:

数据本身就是Key-Value的存在方式,所谓的数据倾斜就是说某(几)个Key的Values特别多,如果要解决数据倾斜,实质上是解决单一的Key的Values的个数特别多的情况,新的的数据倾斜解决方案由此诞生了:

1,把一个大的Key-Values的数据分解成为Key-subKey-Values的方式;例如数据原来的Key值是ID,ID下面包括省份、城市、社区等很多数据,现在把Key变成ID+省份+城市+社区的方式,这样把原来庞大的Value的集合变成了更细化的数据。

2,预先和其他表进行join,将数据倾斜提前到上游的Hive ETL;

3,可以把大的Key-Values中的Values组拼成为一个字符串,从而形成只有一个元素的Key-Value;

4,加一个中间适配层,当数据进来的时候进行Key的统计和动态排名,基于该排名动态的调整Key分布;这种情况表示数据倾斜特别严重,此时可以使用内存级别的数据库,不断统计Key值并进行排名,如果Key值特别多可以对Key值进行调整,如触发一个过程,将Key值加上一个时间戳,以时间为考虑因素改变Key的分布。

5, 假如10万个Key都发生了数据倾斜,如何解决呢?此时一般就是加内存和Cores!如出现OOM就加内存,运行特别慢就加Cores。