SparkCore — Shuffle操作

Spark的shuffle操作

  Spark的shuffle操作分为HashShuffle和SortShuffle,两种shuffle(还有一种tungsten-sort shuffle,这个没有研究过)。其中在Spark1.2版本之前默认的都是HashShuffle操作,HashShuffle有一个非常严重的弊端就是在没有开启consolidation机制的情况下,会产生大量的中间磁盘文件,这对性能有很大的影响;而在Spark1.2版本之后,默认的Shuffle,就改成了SortShuffle,相比于HashShuffle,SortShuffle虽然也会产生中间文件,但是在map output的时候,会将这些临时文件进行聚合,生成一个磁盘文件,因此每个Task就只有一个磁盘文件,reduce在拉取数据的时候,根据索引中的位移信息就可以拉取到自己的信息。
  在知道Spark Shuffle有不同的版本之后,我们先从老版本开始分析,之前设计的shuffle的弊端在哪里,然后在分析新的版本。(这里分析的前提条件是,数据比较大,内存缓存不够,会溢写到磁盘。)

HashShuffle
未开启consolidation机制

  发生shuffle的操作,主要是使用到了对key进行操作的算子,比如reduceByKey、groupByKey等。
  普通的shuffle操作,如下图所示:
普通shuffle
  假设每个worker的每个executor只有一个cpu core,意思就是每个时间只有一个task在运行,reduce端有4个task。在普通机制下,map端的每个task都会为reduce端的task创建一份属于它的文件,也就是说每个ShuffleMapTask会为每个ReduceTask创建一份属于它的文件,那么就创建了4个文件,假设map端有4个Task并行运行,那么这个stage结束之后,就会创建16分临时文件。

开启了consolidation机制

  假设开启了consolidation机制的HashShuffle,它的过程如下:
consolidation
  和上述一样的情况,开启了Consolidation机制的shuffle,在Map端输出文件的时候,每一个节点上的Task,在第一个task运行的时候创建了4个对应ReduceTask的文件,在这个Task运行结束,下一个Task开始的时候,就会复用之前的Task创建的文件,不会在创建新的文件。因此整个stage运行结束后,只创建了8个文件,相比于之前的普通机制,少了8个。
  虽然HashShuffle在开启了Consolidation机制后,磁盘文件减少很多,但是在task数量很多的时候,产生的磁盘文件依然很可观,比如10个executor,每个executor 5个cpu core,reduce端task数量是50个,那么会产生 10 * 5 * 50 = 2500个磁盘文件,依然很多。而SortShuffle却没有这种情况,它的每个Task只会为所有的ReduceTask创建一份文件 ,加上一份索引文件,记录每个partition的数据位置。下面我们先分析一下它的原理。

SortShuffle
普通机制

  SortShuffle的普通机制是在ReduceTask小于200(spark.shuffle.sort.bypassMergeThreshold默认是200)的时候,运行的就是普通机制,超过就是bypass机制。普通机制它会对数据先进行排序,然后再写入到文件。而bypass机制没有排序这个环节。下面先看图:
在这里插入图片描述
  首先Task会将数据存入缓存,当达到一定阈值之后(有两个阈值判断,一个是myMemoryThreshold默认是5M,但是当超过5M时会先向TaskMemoryManager申请内存,进行扩容,但是最终还是需要写入磁盘文件;还有一个阈值就是Long.MAX_VALUE;只要超过其中的一个,就会发生溢写磁盘文件操作),就会根据key将数据进行排序,排序后分批写入磁盘文件,默认是10000条,也就是说数据会以每批10000条的数据分批写入磁盘(写入磁盘是使用的Java BufferedOutputStream,会先将数据缓存在内存中,当缓存溢满之后再写入磁盘,减少IO操作),产生一个临时文件。在数据量比较大的时候,一个Task将数据写入磁盘的时候,可能会产生多个临时文件,在Task结束的时候,会将这些临时文件进行聚合merge成一个文件,写入磁盘,并且还会生成一个索引文件,记录每个partition的数据位置(Offset)。

bypass机制

bypass
  相比于普通机制,bypass它没有排序这一个功能,它的每个Task都会为ReduceTask创建一个文件,这和未开启consolidation机制的HashShuffle是一样的,不同的是,它在最后做了一个合并文件的操作,并创建一个单独的索引。这对于ResultTask而言read的性能会更好些。
  目前Spark1.2版本之后默认使用的是,SortShuffle(不过目前在Spark新版本中已经弃用了HashShuffle,当然这并不妨碍我们学习它的设计思想。),它的两种机制上面已经分析过了,最主要的区别就是一个会按照key对数据进行排序,一个不需要排序,它们相对于HashShuffle而言,Task端最终输出的文件要少的多,其实在产生的临时文件的数量上,SortShuffle同样不少,不过它最终会合并这些文件,然后删除,这点需要注意。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值