spark Shuffle过程分析


普通shuffle过程

shuffle过程是spark运算的重要过程,也是spark调优的关键地方之一,在spark中的reduceByKey,groupByKey,sortByKey,countByKey,join,cogroup等操作时,都会触发shuffle过程。shuffle过程发生在shuffleMapTask与resultTask之间,当shuffleMapTask的输出数据先放到内存bucket中,bucket会shuffleMapTask的输出Mapstatus,发送给DAGScheduler的mapoutputTrackerMaster。然后将数据写入shuffleblockFile磁盘文件。resultTask会用blockStoreShuffleFetcher去MapoutputTrackerMaster获取到要拉取的文件信息,然后通过blockManager拉取该磁盘文件。每个resultTask拉取过来的数据,是一个shuffledRDD,优先写入内存,内存不够写入磁盘。然后每个resultTask对数据进行聚合,最后生成MapPartitionsRDD,然后执行算子。map端默认内存缓存是100K,达到阈值就会刷磁盘,这种方式避免了早期版本中对内存大小的依赖,避免OOM。但是也可能数据过大造成频繁刷写磁盘。

此处与MR不同的是,MR要在map数据文件全部写入磁盘后才可以拉取文件,因为mr需要对数据排序,需要map全部写完排序后才进行reduce端拉取;但是spark不会在map端排序,所以map端只要写一些数据,reduce端就可以进行拉取计算。因此速度上spark要比mr快,但是mr的reduce处理很方便,但是spark不能提供直接处理key对应的value,没有mr的reduce方便。

优化shuffle过程

以上过程是普通的shuffle过程,但是该shuffle过程最大的问题是产生的磁盘文件太多,后面的版本中对此进行了优化,即spark的consolidation机制,也就是shuffleGroup概念。一个shuffleMapTask将写入resultTask数量的本地文件,当下一个shuffleMapTask运行的时候,可以将数据写入之前的shuffleMapTask的本地文件,相当于对多个shuffleMapTask的数据进行了合并,也就是其他的shuffleMapTask的输出会复用前一个shuffleMapTask的内存缓存和磁盘文件。复用的shuffleMapTask组成为一组shuffleGroup,通过索引标注shuffledBlockFile中每个shuffleMapTask输出的位置。每个shuffleMapTask输出的数据称为一个segment。从未减少了本地磁盘的数量。开启了consolidation的shuffle后,每个节点上磁盘文件的数量就是CPU core数量 * resultTask数量。

上面的文章分析中,在shuffleMapTask类中,当执行到writer.write(rdd.iterator(partition, context).asInstanceOf[Iterator[_ <: Product2[Any, Any]]])时候,ShuffleWriter的write方法就是对数据的map端写入操作。  默认的writer是org.apache.spark.shuffle.hash下的HashShuffleWriter,下面分析该类的write方法,该方法将map的输出写入本地磁盘

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值