一、数据倾斜危害?
单个或少数的节点数据量特别大,但一个 Stage 所耗费的时间,是由最慢的那个 Task 决定,所以数据倾斜会导致两个后果:
- OOM(单或少数的节点);
- 拖慢整个Job执行时间(其他已经完成的节点都在等这个还在做的节点)。
二、数据倾斜的现象
当发现如下现象时,十有八九是发生数据倾斜了:
-
绝大多数 task 执行得都非常快,但个别 task 执行极慢,整体任务卡在某个阶段不能结束。
-
原本能够正常执行的 Spark 作业,某天突然报出 OOM(内存溢出)异常。
三、导致Spark数据倾斜的本质
在进行 shuffle 的时候,必须将各个节点上相同的 key 拉取到某个节点上的一个 task 来进行处理,比如按照 key 进行聚合或 join 等操作。此时如果某个 key 对应的数据量特别大的话,就会发生数据倾斜。比如大部分 key 对应10条数据,但是个别 key 却对应了100万条数据,那么大部分 task 可能就只会分配到10条数据,然后1秒钟就运行完了;但是个别 task 可能分配到了100万数据,要运行一两个小时。
四、定位最慢的Task所处的源码位置
步骤一:看数据倾斜发生在哪个stage。yarn-client模式下查看本地log或Spark Web UI中当前运行的是哪个stage;yarn-cluster模式下,通过Spark Web UI查看运行到了哪个Stage。
主要看最慢的Stage各task分配的数据量,来确定是否是数据倾斜。
步骤二:根据Stage划分,推算倾斜发生的代码(必然有Shuffle类算子)。
根据stage划分原理,推算出来发生倾斜的那个stage对应代码中的哪一部分,这部分代码中肯定会有一个shuffle类算子。简单实用方法:只要看到shuffle类算子或Spark SQL的SQL语句会有Shuffle类的算子的句子,就可以知道该地方划分为前后两个Stage。(用Python的PySpark接口,Spark Web UI会查看task在源码中的行数。)
五、解决方案