spark源码分析之ShuffleExternalSorter

概述

ShuffleExternalSorter是专门用于sort-based shuffle的external sorter。

传入的record会被追加到data page。当所有的record都已经插入该sorter时,或者当前线程的shuffle memory已经到达阈值时,会使用ShuffleInMemorySorter来根据record的partition id将record排序。排序后的record然后会被写入一个输出文件(或者多个文件,如果我们已经spill),输出文件的格式,与最终SortShuffleSorter写入的输出文件的格式是一致的。SortShuffleSorter会将每个输出partition的record写入一个序列化的、压缩的流,可以通过一个解压缩的、反序列化的流读取。

与org.apache.spark.util.collection.ExternalSorter不同,这个sorter不会合并spill file。相反,合并操作交给了UnsafeShuffleWriter执行,UnsafeShuffleWriter会使用专门的合并方法来避免额外的序列化和反序列化。

源码分析

成员变量

ShuffleExternalSorter有以下几个比较重要的成员变量:

  • allocatedPages是用来保存待排序的record的page(MemoryBlock)链表。当发生spill后,链表中page就会被释放;
  • spills是将排序后的record写入磁盘文件作为spill file后,这些spill file的元数据信息。
  • inMemSorter是用来根据record的partition id将record排序的ShuffleInMemorySorter。
  • currentPage,page链表中用于保存待排序的record的当前page。一个page会保存多个record,record通过追加的方式添加到page。
  • pageCursor,record追加到当前page时,当前page的可用空间的起始地址(或下标)。
/**
   * Memory pages that hold the records being sorted. The pages in this list are freed when
   * spilling, although in principle we could recycle these pages across spills (on the other hand,
   * this might not be necessary if we maintained a pool of re-usable pages in the TaskMemoryManager
   * itself).
   */
   //用page链表保存待排序的record。当发生spill时,链表中的page会被释放,虽然原则上我们可以在整个spill期间
   //循环利用这些page(另一方面,这可能是不必要的如果我们在TaskMemoryManager中保存了一个可重复使用的page pool)
  private final LinkedList<MemoryBlock> allocatedPages = new LinkedList<>();

  private final LinkedList<SpillInfo> spills = new LinkedList<>();

  // These variables are reset after spilling:
  //spill之后会重置这些变量
  @Nullable private ShuffleInMemorySorter inMemSorter;
  @Nullable private MemoryBlock currentPage = null;
  private long pageCursor = -1;

 其中,inMemsorter的初始化如下:

它会从sparkConf中获取配置信息判断是否使用RadixSort对record进行排序,默认为true。

 this.inMemSorter = new ShuffleInMemorySorter(
      this, initialSize, conf.getBoolean("spark.shuffle.sort.useRadixSort", true));

insertRecord方法

插入一条record到shuffle external sorter。即追加一条record到当前page。record在当前page中的存储格式为:

record length | (k, v)

同时它也会插入一条record到ShuffleInMemorySorter,在inMemorySorter中保存record的编码地址和partitionId。record在inMemorySorter的存储格式为:

partitionId | pageNumber | offset in page

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值