Spark Shuffle源码分析系列之BypassMergeSortShuffleWriter

BypassMergeSortShuffleWriter实现了Hash风格的Shuffle机制,和已经废弃的HashShuffleWriter类似。这个shuffle writer将传入的record写入单独的文件,每个reduce partition对应一个文件,然后拼接这些文件汇总成一个单独的输出文件。这个输出文件按照partitionId分成多个区域,并生成相应的索引文件,Reducer会根据索引问价中各个partitionId的偏移量来fetch对应的数据。

BypassMergeSortShuffleWriter应用场景

BypassMergeSortShuffleWriter的原理中我们可以看到,这种Writer的在存在大量的reduce partition时,是低效率的,因为它会同时对每个partition都打开一个serializer和文件流,另外它是直接写入文件,不需要内存操作,所以排序和map-side聚合是不能指定的,所以使用时候需要满足以下几个条件:

  1. 不能指定ordering,即在partition内不能排序;
  2. 不能指定Aggregator,即不能进行map端的聚合;
  3. parttition的数量要小于spark.shuffle.sort.bypassMergeThreshold指定的阈值,默认200.

对应的源码分析如下:

// org.apache.spark.shuffle.sort.SortShuffleWriter

// 用于判断是否绕开合并和排序
def shouldBypassMergeSort(conf: SparkConf, dep: ShuffleDependency[_, _, _]): Boolean = {
   
  if (dep.mapSideCombine) {
    // 启用了Map端Combine,则不可使用BypassMergeSort
    require(dep.aggregator.isDefined, "Map-side combine without Aggregator specified!")
    false
  } else {
   
    // 如果ShuffleDependency的mapSideCombine属性为false,
    // 且ShuffleDependency的分区计算器中的分区数量小于等于bypassMergeThreshold,返回true
    val bypassMergeThreshold: Int = conf.getInt("spark.shuffle.sort.bypassMergeThreshold", 200)
    dep.partitioner.numPartitions <= bypassMergeThreshold
  }
}

整体架构

该种ShuffleWriter原理如下图所示:

在这里插入图片描述

从图中我们可以看出经过以下步骤:

  1. 首先根据分区函数,将不同分区的数据写到不同的分区文件中;
  2. 将多个分区文件按照分区id从小到大的顺序依次写入到数据文件中,并得到各个分区的大小;
  3. 根据各个分区的大小,生成相应的索引文件。
    下面我们来具体看下写入过程。

文件写入

write方法将迭代器中的数据写入到文件中,实现如下:

  1. 首先检查迭代器中是否有数据,没有数据,直接生成索引文件返回即可;
  2. 如果有数据,则首先为每个partition创建一个临时文件和一个DiskBlockobjectWriterDiskBlockobjectWriter用于写数据到该临时文件中;
  3. 遍历迭代器中数据,对每个record使用分区函数计算出相应的分区ID,然后调用此分区ID对应的DiskBlockObjectWriterwrite方法,向临时Shuffle文件的输出流中写入键值对;
  4. 遍历完成后,提交缓冲区中的数据,全部写入磁盘,得到各个分区的文件信息;
  5. 通过writePartitionedFile合并多个文件,合并每个partition对应的文件到一个Temp文件中;
  6. 使用shuffleBlockResolver来生成Block文件对应的索引文件和最终的数据文件,其中会校验文件大小和各个区的大小,然后生成最终的数据和索引文件。
public void write(Iterator<Product2<K, V>> records) throws IOException {
   
  assert (partitionWriters == 
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值