spark运行时reduce端任务数

Tasks数决定因素
在Spark 中 我们知道会将一个任务划分为多个stage ,划分stage的依据就是是否为宽依赖(存在shuffle),每个stage 的并行度取决于一个stage 最后一个算子,因为一个任务的调用是从最后一个算子向前执行的.所以一个任务的task 数主要看一个stage最后的一个rdd的分区数。

这里主要用一个列子说明计算过程分区数是怎么确定的:

rdd.map(...).reduceByKey(...).collect()     

根据上面这段逻辑可以知道 map 中主要返回的是一个mapPartitionsRdd reduceByKey返回的是一个ShuffleRdd 。
mapPartitionRDD 中获取分区的方法:

 override val partitioner = if (preservesPartitioning) firstParent[T].partitioner else None

这里可以看到这里获取的是父RDD的分区,我们在实际过程中可能从集合 或者文件中读取所以这里的分区主要是看从文件中读取文件时会生成多少个Task 以及在使用集合创建RDD时 我们给定的分区数是多少,假设这个地方我们获取分区的方法不是直接从父RDD获取的 比如父RDD的分区是 5 我们这里定义的getPartition方法可以按照一个范围 例如将父RDD 的分区 按照 1-2 作为一个分区 3-5作为一个分区 那这里就变成了两个分区所以此时整个这个stage 最后的task 就会变成了2 个 这个部分可以直接对比colecse.

关于shuffle reduce的数量:
根据一些算子的定义是可以自己传入一个分区器 分区器中定义了相关分区数的操作 默认都是HashPartitoner 并且数量默认是:spark.default.parallelism (默认200)所以默认情况下这个参数会决定reduce端任务的并行度,这里如果没有配置这个参数的话则会以map端的partitions数一致【sortWriter在写出数据时也是根据ShuffleRDD的分区数写出到文件中的】
可以参考如下代码:

在org.apache.spark.Partitioner的 defaultPartitioner 方法中

          // 获取spark.default.parallelism参数配置的值
      if (rdd.context.conf.contains("spark.default.parallelism")) {
         //这里直接就是用的此参数配置的值作为reduce分区数
        new HashPartitioner(rdd.context.defaultParallelism)
      } else {
        //这里直接就用Map端的分区数了  就是map  reduce 的分区一致
        new HashPartitioner(rdds.map(_.partitions.length).max)
      }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值