目录:
1、 什么是数据倾斜????(基于Spark 架构)
2、何谓数据倾斜????
3、数据倾斜是如何造成的????
4、数据倾斜是如何解决的????
什么是数据倾斜???
对 Spark/Hadoop 这样的大数据系统来讲,数据量大并不可怕,可怕的是数据倾斜。
何谓数据倾斜???
数据倾斜指的是,并行处理的数据集中,某一部分(如Spark 或 Kafka 的一个 Partition)的数据显著多于其它部分,从而使得该部分的处理速度成为整个数据集处理的瓶颈。
数据倾斜是如何造成的????
在 Shuffle 阶段。同样 Key 的数据条数太多了。导致了某个 key(上图中的 80 亿条)所在的 Task 数据量太大了。远远超过其他 Task 所处理的数据量。
一个经验结论是:一般情况下,OOM 的原因都是数据倾斜。某个 task任务数据量太大,GC 的压力就很大。这比不了 Kafka,因为 kafka 的内存是不经过 JVM 的。是基于 Linux 内核的 Page。
数据倾斜是如何解决的????
1.仔细查看定位导致数据倾斜的代码。(数据倾斜只会发生在 shuffle 过程中)
可能会触发 shuffle 操作的算子:distinct、groupByKey、reduceByKey、aggregateByKey、join、cogroup、repartition 等。
出现数据倾斜时,可能就是你的代码中使用了这些算子中的某一个所导致的。
2.某个 task 执行特别慢的情况
首先查看的是数据倾斜发生在第几个Stage中。。
可以通过 Spark Web UI 来查看当前运行到了第几个 stage,看一下当前这个 stage 各个 task 分配的数据量,从而进一步确定是不是 task 分配的数据不均匀导致了数据倾斜。
3.某个 task 莫名其妙内存溢出的情况
这种情况下去定位出问题的代码就比较容易了。我们建议直接看yarn-client 模式下本地 log 的异常栈,或者是通过 YARN 查看 yarn-cluster模式下的 log 中的异常栈。一般来说,通过异常栈信息就可以定位到你的代码中哪一行发生了内存溢出。
然后在那行代码附近找找,一般也会有shuffle 类算子,此时很可能就是这个算子导致了数据倾斜。
但是大家要注意的是,不能单纯靠偶然的内存溢出就判定发生了数据倾斜。
因为自己编写的代码的 bug,以及偶然出现的数据异常,也可能会导致内存溢出。
因此还是要按照上面所讲的方法,通过 Spark Web UI 查看报错的那个 stage 的各个 task 的运行时间以及分配的数据量,才能确定是否是由于数据倾斜才导致了这次内存溢出。
4.查看导致数据倾斜的 key 的数据分布情况
知道了数据倾斜发生在哪里之后,通常需要分析一下那个执行了shuffle 操作并且导致了数据倾斜的 RDD/Hive 表,查看一下其中 key 的分布情况。
5.自定义 Partitioner
原理:
使用自定义的 Partitioner(默认为 HashPartitioner),将原本被分配到同一个 Task 的不同 Key 分配到不同 Task。
6.为数据倾斜的 key 增加随机前/后缀
原理:
为数据量特别大的 Key 增加随机前/后缀,使得原来 Key 相同的数据
变为 Key 不相同的数据,从而使倾斜的数据集分散到不同的 Task 中,彻底
解决数据倾斜问题。Join 另一侧的数据中,与倾斜 Key 对应的部分数据,
与随机前缀集作笛卡尔乘积,从而保证无论数据倾斜侧倾斜 Key 如何加前
缀,都能与之正常 Join。