Spark Sort Shuffle 总结

目录

前提知识:

Shuffle图解

SortShuffleManager

Sort Shuffle

流程图

Shuffle Write

Shuffle Read

BypassMergeSortShuffle

流程图

 Bypass机制触发条件

Spark Shuffle处理器


前提知识:

宽依赖:上游RDD中的一个分区中的数据,被下游RDD的多个分区所共享,称为一对多

窄依赖:上游RDD中的一个分区中的数据,被下游RDD的一个分区所共享,称为一对一

Shuffle图解

SortShuffleManager

Sort Shuffle

流程图

Shuffle Write

task阶段划分的时候,会创建ShuffleMapTaskResultTask,在ShuffleMapTask进行write操作ResultTask进行read的操作,在write时,会根据Handle处理器决定调用哪个Writer类,有三种处理器SerializedShuffleHandle、BypassMergeSortShuffleHandle、BaseShuffleHandle,这三个处理器分别对应UnsafeShuffleWriter、BypassMergeSortShuffleWriter、SortShuffleWriter。如果是reduceBykey有预聚合的算子,走SortShuffleWriter。在写数据时会判断是否shouldCombine,如果需要combin,根据key得到分区,修改对应key的value,并判断是否要Spill磁盘,当

1.elementsRead % 32 == 0 && currentMemory >= 5*1024*1024 (5M)

  当满足1时,同时满足2.申请的资源不足

2.shouldSpill = currentMemory >= myMemoryThreshold

当数据大于Int的最大值时候,强制溢写
3.shouldSpill = shouldSpill || _elementsRead > numElementsForceSpillThreshold

如果只是数据没有spill到磁盘,only-memory data,不进行merge,如果需要order(reduceByKey,但是数据量很小没有spill)的话,需要现根据分区id再根据key排序

 如果数据spill到磁盘,当溢写到磁盘时进行merge操作(磁盘文件和内存都merge ),现根据分区再根据key进行排序  归并排序使用的排序算法是堆排序,先写入缓冲区(32k),然后溢写到磁盘,最后释放内存。

最后将早期的IndexFile和dataFile删除,将indexTmp.renameTo(indexFile)、dataTmp.renameTo(dataFile)

Shuffle Read

 读磁盘文件有个缓冲区48M

BypassMergeSortShuffle

流程图

 Bypass机制触发条件

   if (dep.mapSideCombine) {
      false
    } else {
      val bypassMergeThreshold: Int = conf.get(config.SHUFFLE_SORT_BYPASS_MERGE_THRESHOLD)
      dep.partitioner.numPartitions <= bypassMergeThreshold
    }

 private[spark] val SHUFFLE_SORT_BYPASS_MERGE_THRESHOLD =
    ConfigBuilder("spark.shuffle.sort.bypassMergeThreshold")
      .doc("In the sort-based shuffle manager, avoid merge-sorting data if there is no " +
        "map-side aggregation and there are at most this many reduce partitions")
      .version("1.1.1")
      .intConf
      .createWithDefault(200)

1.不是预聚合算子

2.下游分区数量数量小于等于spark.shuffle.sort.bypassMergeThreshold参数的值。 200 

Spark Shuffle处理器

处理器调用类条件
unsafeShuffleHandleUnsafeShuffleWriter

1.序列化重定位 kryo支持,java不支持

2.不能使用预聚合

3.下游分区数量小于或等于16777215

bypassMergeSortHandleBypassMergeSortShuffleWriter

1.不能使用预聚合

2.下游分区数量小于等于200

例如:groupbykey

BaseShuffleHandleBaseShuffleHandle其他情况 例如:reduceByKey

SortShuffleManager中getWriter方法
 handle match {
      case unsafeShuffleHandle: SerializedShuffleHandle[K @unchecked, V @unchecked] =>
        new UnsafeShuffleWriter(
          env.blockManager,
          context.taskMemoryManager(),
          unsafeShuffleHandle,
          mapId,
          context,
          env.conf,
          metrics,
          shuffleExecutorComponents)
      case bypassMergeSortHandle: BypassMergeSortShuffleHandle[K @unchecked, V @unchecked] =>
        new BypassMergeSortShuffleWriter(
          env.blockManager,
          bypassMergeSortHandle,
          mapId,
          env.conf,
          metrics,
          shuffleExecutorComponents)
      case other: BaseShuffleHandle[K @unchecked, V @unchecked, _] =>
        new SortShuffleWriter(
          shuffleBlockResolver, other, mapId, context, shuffleExecutorComponents)
    }

bypass不用进行排序所以效率比sort shuffle高,但是和没优化的HashShuffle一样,会产生很多的临时文件,所以不适用分区特别多的情况

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值