【问题标题】:Order of task execution in union() operationunion() 操作中的任务执行顺序
【发布时间】:2018-12-28 02:39:22
【问题描述】:

我有一个包含 80 个 rdds 的列表,我想处理然后最终加入。 “过程”部分包括为每个 rdd 做一个 map 和一个 reduce 键。 然后我通过联合来“加入”他们。 这是我的代码草图:

rdds0.foreach(_.persist()) //rdds0 are persisted

//trigger a map and a shuffle for each rdd
vals rdds = rdds0.map(rdd => rdd.map(f1).reduceByKey(f2))

//action on the union of the rdds
sparkContext.union(rdds).collect()

但是,生成的 DAG 存在问题。 确实spark生成的DAG是这样的:

  • 80 个阶段,每个 RDD 的每个“地图”一个阶段

  • 联合的最后阶段,以 80 个 reduceByKey 并行开始

我对粗体部分有疑问。 AFAIK,这意味着对于最后一个任务,Spark 将并行调度 80 个 reducebykey,其中每个都占用大量内存。 一旦为此 RDD 完成了 map 阶段,就能够为每个 rdd 单独执行 reduceByKey() 似乎更有效。 相反,在 所有 map 阶段完成之前不能执行 reduceByKey,然后它们都被同时调度。

有没有办法强制 Spark 以某种方式尽快执行 redueByKey() 操作,而不是等待所有地图任务? 我认为这是 union() 创建 PartitionerAwareUnionRDD 而不是 UnionRDD() 的问题,但似乎两种 RDD 类型都会生成相同的 DAG。

【问题讨论】:

    标签: scala apache-spark


    【解决方案1】:

    reduceByKey 是一个广泛的转换 - 这意味着它具有:

    • “map-side”组件 - 在 shuffle 之前发生的操作的一部分 - 包含在 DAG 的第一阶段。
    • “reduce-side”组件 - 洗牌后发生的操作的一部分 - 包含在 DAG 的第二阶段。

    “reduce-side”组件的结果直接通过管道传送到联合。在这种情况下,确实没有什么可优化的。

    【讨论】:

    • 我不确定我们在谈论同一件事......我知道reduce的一部分是在地图端完成的。但是我不明白为什么“减少端”部分没有尽快完成(即当一个地图完成时),那么减少的结果可以在需要时用于联合。在我的示例中,发生的情况是所有reduce 端reduce 都是同时完成的,这似乎会同时触发大量通信
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2018-12-25
    • 2020-02-26
    相关资源
    最近更新 更多