Spark源码之coalesce算子

1、问题背景

        总所周知,spark的rdd编程中有两个算子repartition和coalesce。公开的资料上定义为,两者都是对spark分区数进行调整的算子。

        repartition会经过shuffle,其实际上就是调用的coalesce(shuffle=true)。

        coalesce,默认shuffle=false,不会经过shuffle。

        当前仅针对coalesce算子考虑,我们看一下官方的定义:

        大概意思为:如果你想要从1000个分区到100个分区,并且不经过shuffle,近乎平均分配10个父分区到1个子分区。

        首先我说下我个人简单理解:不经过shuffle,就意味着coalesce算子前后都是在一个stage中的。从该stage开始到coalesce算子之前的任务的迭代执行的并行度都是1000,从coalesce算子开始到该stage结束的任务的迭代执行的并行度都是100。

2、问题及复现

        但是在实际使用过程中发现,对于在一个stage中的多个算子,如果先进行map、之后再coalesce(1),该stage的输出的并行度确实为1,但是coalesce之前的map算子的并行度也被缩减为1。这样看的话,似乎和官方的定义有些冲突。

        因此简单对此问题进行了复现:

        按照我的理解,应该有两个stage,并行读的变化流程应该为

        textFlie(N) → repartition(4) → map(4) → coalesce(2) → count(2)

        但是实际为,确实有两个stage,但是第二个stage的task数量始终为2,并没有中间4这个过程。

        此外对于spark的并行度,具体的实现即是TaskRunner线程。通过VisualVM监控,第二个stage也始终只有2个TaskRunner线程。

3、问题分析

        了解过spark的调度过程的都应该清楚。

        首先application根据行动算子生成job,

        job根据宽窄依赖切分stage,

        stage根据最后一个rdd的分区数决定stage的并行度,即此stage中task的数量。

        这么看的话,当前stage的最后一个rdd的并行度应该是coalesce之后的并行度,进而整个stage的task数量也就是缩减之后的了。

        这么分析的话和实际执行的效果是一致的,但是coalesce官方定义的效果并不一致,coalesce并没有缩减分区,而是强制将整个stage的并行度都降低了。

4、coalesce源码分析

        从coalesce源码看,shuffle=false的情况下,只是对现有rdd重新装饰为了一个新的CoalescedRDD。但是该Rdd的Partition有所不同,其实现为CoalescedRDDPartition类,内部维护了一个多对一的映射关系(看似是存在分区合并)。

5、调度源码分析

        所谓spark的并行度就是TaskRunner线程的数量,根据源码分析,task线程的数量取决于触发宽依赖或者触发行动算子的rdd的并行度,对于coalesce问题来讲,就是coalesce算子之后的并行度,这与我的猜想也相符。

        源码追踪暂时略过,后续在加。

6、总结

        首先可以确定的是,executor实际启动的TaskRunner线程数肯定是coalesce算子缩减之后的并行度。

        但是为什么CoalescedRDD还有所有不同之处呢?以我上面测试的例子为例。我猜想CoalescedRDD所在的Stage的上一个Stage再Shuffle Write的时候是按照coalesce算子之前的并行度4输出的。而Shuffle Read读取时虽然还是只有2个线程,但是仍然读取4个分区(4个分区两两顺序排列,而不是完全并行的),然后到coalesce算子时再合并为2个分区的。见下图

        所谓spark的分布式计算,其原理就是再多机、多进程、多线程上采用分治的思想并行的进行计算。而上例中虽然时4个分区,但是是两两顺序排列的,因此并不是完全意义的并行性4。由此可简见和源码的解释稍有歧义。实际计算性能也会有很大差异。

 

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值