数据倾斜的原因以及解决方案


在开发过程中大家都会遇到一个常见的问题,那就是数据倾斜。既然遇到问题,那么就应该想办法解决问题。解决问题首先要了解出现这个问题的原因。

   什么是数据倾斜,比如说:在hive中 map阶段早就跑完了,reduce阶段一直卡在99%。很大情况是发生了数据倾斜,整个任务在等某个节点跑完。 在spark中大部分的task执行的特别快,

                剩下的一些task执行的特别慢,要几分钟或几十分钟才执行完一个task Hive中大表join的时候,容易产生数据倾斜问题,spark中产生shuffle类算子的操作,groupbykey、reducebykey、join等操作

                会引起数据倾斜。

   数据倾斜的原因:在进行shuffle的时候,必须 将各个节点上相同的 key 拉取到某个节点上的一个 task 来进行处理 ,比如按照key进行聚合或join等操作。此时如果某个 key对应的数据量特别大的话,

           就会发生数据倾斜。比如大部分key对应10条数据,但是个别key却对应了100万条数据,那么大部分task可能就只 会分配到10条数据,然后1秒钟就运行完了;但是个别task可能分配到了100万数据,

           要运行一两个小时。

   解决方案:

    第一点:直接过滤掉那些引起倾斜的Key。这种方法很简单,既然你倾斜,那我不用你就完事。比如说,总共有100万个key。只有2 个key,是数据量达到10 万的。其他所有的key,对应的数量都是几十,这样join

        后会引起倾斜。这个时候,自 己可以去取舍,如果业务和需求可以理解和接受的话,在从hive 表查询源数据的时候,直接在sql 中 用 where 条件,过滤掉某几个 key 。那么这几个 原先有大量数据,会导致数据倾

        斜的key,被过滤掉之后,那么在的spark作业中,自然就不会发生数据倾斜了。

    第二点:Hive ETL做处理

        通过Hive ETL预先对数据按照key进行聚合,或者是预先和其他表进行join,然后在Spark作业中针对的数据源就不是原来的Hive表了,而是预处 理后的Hive表。此时由于数据已经预先进行过

        聚合或join操作了,那么在Spark作业中也就不需要使用原先的shuffle类算子执行这类操作了。Hive ETL中进行group by或者join等shuffle操作时,还是会出现数据倾斜,导致Hive ETL的速度很慢。我们只是把数据倾斜

        的发生提前到了Hive ETL中。

    第三点:提高shuffle的操作并行度

        在对RDD执行shuffle算子时,给shuffle算子传入一个参数,比如reduceByKey(1000),该参数就设置了这个shuffle算子执行时shuffle read task 的数量。对于Spark SQL中的shuffle类语句,比如group by、join等。

        需要设置一个参数,即spark.sql.shuffle.partitions,该参数代表了shuffle read task的并行度,该值默认是200,对于很多场景来说都有点过小

 

        其原理很简单,增加shuffle read task的数量,可以 让原本分配给一个 task 的多个 key 分配给多个 task , 从而让每个 task 处理比原来更少的数据 。举例来说, 如果原本有5个key,每个key对应10条数据,这

        5个key都是分配给一个task的,那么这个task就要处理50条数据。而增加了shuffle read task以后, 每个task就分配到一个key,即每个task就处理10条数据,那么自然每个task的执行时间都会变短了

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM