如何避免生产Spark Shuffle的场景

一、概述
二、方案适用场景
三、方案实现思路
四、方案实现原理
五、方案优点
六、方案缺点
七、代码实现

一、概述

有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多。数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的性能。

二、方案适用场景

在对RDD使用join类操作,或者是在Spark SQL中使用join语句,而且join操作中的一个RDD或表的数据量比较小(几百M或一两G),比较适合此方案。

三、基本实现思路:

不使用join算子进行连接操作,而使用Broadcast变量与map类算子实现join操作,进而完全规避掉shuffle类的操作,彻底避免数据倾斜的发生。
将较小的RDD中的数据直接通过collect算子拉取到Driver端的内存中来,然后对其创建一个Broadcast变量;
接着对另外一个RDD执行map类算子,在算子函数中,从Broadcast变量中获取较小RDD的全量数据,与当前RDD的每一条数据按照连接key进行比对,如果连接key相同的话,那么就将两个RDD的数据用你需要的方式连接起来。

四、方案实现原理

普通的join是会走shuffle过程的,而一旦shuffle,就相当于会将相同key的数据拉取到一个shuffle read task 中再进行join,此时就是reduce join。 但是如果一个RDD是较小的,则可以采用广播小RDD的全量数据+map算子来实现与join同样的效果,此时不产生shuffle操作,也就规避了数据倾斜。

五、方案优点

	对join操作导致的数据倾斜,效果非常好,因为根本就不会发生shuffle,也就根本不会发生数据倾斜。

六、方案缺点

只适用于一个大表和一个小表的情况。我们需要将小表进行广播,此时会消耗内存资源,driver和每个Executor内存中都会驻留一份小RDD的全量数据。如果我们广播出去的RDD数据较大,比如10G以上,那么就可能发生内存溢出了,所以不适用于两个都是大表的情况。
  • 如果对于hive中的map join熟悉的同学看到这幅图应该很好理解,所以建议大家看看hive中的map join原理,进行学习。

      ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190823171430136.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poaWthbmppYW5p,size_16,color_FFFFFF,t_70)
    

七、代码实现:

object BroadCastApp{
		def main(args: Array[String]: Unit = {
				val conf = new SparkConf().setAppName("BroadCastApp").setMaster("local[2]")
				val sc = new SparkContext(conf)

			val smallRDD = sc.parallelize(Array(("1","ruoze"),("2","jepson"),("3","xingxing"))).collectAsMap()

			val smallBroadCast = sc.broadcast(smallRDD)
			
			val bigRDD = sc.parallelize(Array(("1","school01","male"),("2","school02","female"),("3","school03","male"),("4","school04","female"),("5","school05","male"))).map( x => (x._1,x))
			
			val broadCastValue = smallBroadCast.value
			
			bigRDD.mapPartitions(partitions => {
					for ( (key,value)  <- partitions
					if(broadCastValue.contains(key)))
					yield(key,broadCastValue.getOrElse(key,""),value._2,value._3)
		}).collect().foreach(println)

	}
}

输出信息如下:

(1,ruoze,school01,male)
(2,jepson,school02,female)
(3,xingxing,school03,male)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值