Sort—Based Shuffle源码分析

  ShuffleMapTask的结果(ShuffleMapStage中FinalRDD的数据)都将写入磁盘,以供后续Stage拉取,即整个Shuffle包括前Stage的Shuffle Write和后Stage的Shuffle Read。

Shuffle Write

概述:

  • 写records到内存缓冲区(一个数组维护的map),每次insert&update都需要检查是否达到溢写条件
  • 若需要溢写,将集合中的数据根据partitionId和key(若需要)排序后顺序溢写到一个临时的磁盘文件,并释放内存新建一个map放数据,每次溢写都是写一个新的临时文件
  • 一个task最终对应一个文件,将还在内存中的数据和已经spill的文件根据reduce端的partitionId进行合并,合并后需要再次聚合排序(有需要情况下),再根据partition的顺序写入最终文件,并返回每个partition在文件中的偏移量,最后以MapStatus对象返回给driver并注册到MapOutputTrackerMaster中,后续reduce好通过它来访问

入口:
  执行一个ShuffleMapTask最终的执行逻辑是调用了ShuffleMapTask类的runTask()方法:其中的finalRDD和dependency是在Driver端DAGScheluer中提交Stage的时候加入广播变量的。
  接着通过SparkEnv获取shuffleManager,默认使用的是sort(对应的是org.apache.spark.shuffle.sort.SortShuffleManager),可通过spark.shuffle.manager设置。然后调用了manager.getWriter方法,getWriter返回的是SortShuffleWriter,直接看writer.write发生了什么:

  • 通过判断是否有map端的combine来创建不同的ExternalSorter,若有则将对应的aggregator和keyOrdering作为参数传入
  • 调用sorter.insertAll(records),将records写入内存缓冲区,超过阈值则溢写到磁盘文件
  • Merge内存记录和所有被spill到磁盘的文件,并写到最终的数据文件.data中
  • 将每个partition的偏移量写到index文件中。

先细看sorter.inster是怎么写到内存,并spill到磁盘文件的:

  • 需要聚合的情况,遍历records拿到record的KV,通过map的changeValue方法并根据update函数来对相同K的V进行聚合,这里的map是PartitionedAppendOnlyMap类型,只能添加数据不能删除数据,底层实现是一个数组,数组中存KV键值对的方式是[K1,V1,K2,V2…],每一次操作后都会判断是否要spill到磁盘
  • 不需要聚合的情况,直接将record放入buffer,然后判断是否要溢写到磁盘

先看map.changeValue方法到底是怎么通过map实现对数据combine的:

override def changeValue(key: K, updateFunc: (Boolean, V) => V): V = {
   
   
    // 通过聚合算法得到newValue
    val newValue = super.changeValue(key, updateFunc)
    // 跟新对map的大小采样
    super.afterUpdate()
    newValue
  }

super.changeValue的实现:
根据K的hashCode再哈希与上掩码 得到 pos,2 * pos 为 k 应该所在的位置,2 * pos + 1 为 k 对应的 v 所在的位置,获取k应该所在位置的原来的key:

  • 若原来的key和当前的 k 相等,则通过update函数将两个v进行聚合并更新该位置的value
  • 若原来的key存在但不和当前的k 相等,则说明hash冲突了,更新pos继续遍历
  • 若原来的key不存在,则将当前k作为该位置的key,并通过update函数初始化该k对应的聚合结果,接着会通过incrementSize()方法进行扩容。更新curSize,若当前大小超过了阈值growThreshold(growThreshold是当前容量capacity的0.7倍),
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值