为啥 Apache Spark 的功能不并行?

Posted

技术标签:

【中文标题】为啥 Apache Spark 的功能不并行?【英文标题】:Why Apache Spark take function not parallel?为什么 Apache Spark 的功能不并行? 【发布时间】:2015-02-10 16:21:17 【问题描述】:

在http://spark.apache.org/docs/latest/programming-guide.html 阅读 Apache Spark 指南,它指出:

为什么 take 函数不能并行运行?并行实现此类功能有哪些困难?为了获取 RDD 的前 n 个元素,需要遍历整个 RDD,这是否与事实有关?

【问题讨论】:

【参考方案1】:

实际上,虽然take 不是完全并行的,但也不是完全顺序的。

例如,假设您take(200),每个分区有 10 个元素。 take 将首先获取分区 0 并查看它有 10 个元素。它假设需要 20 个这样的分区才能获得 200 个元素。但最好在并行请求中要求更多。所以它想要 30 个分区,而它已经有 1 个。所以它接下来会并行地获取分区 1 到 29。这很可能是最后一步。如果很不走运,一共没有找到200个元素,它会再次进行估计并并行请求另一个批次。

查看代码,有据可查: https://github.com/apache/spark/blob/v1.2.0/core/src/main/scala/org/apache/spark/rdd/RDD.scala#L1049

我认为文档是错误的。本地计算仅在需要单个分区时发生。这是第一次传递(获取分区 0)的情况,但通常不是后面传递的情况。

【讨论】:

谢谢,当你说它不是“完全”平行时。您是否指的是在“take”功能的评论中指出“它通过首先扫描一个分区来工作”。那么对于 10 个分区,第一个分区将在并行扫描其他 9 个分区之前被扫描? 是的。但在最坏的情况下,它将完全按顺序遍历分区。不过,为此,分区的大小必须呈几何减小——在实践中这不太可能。实际上,分区大小通常是统一的,因此 take 将需要 2 次迭代,就像你描述的那样。 我已发送拉取请求以修复文档。 (github.com/apache/spark/pull/4533) 如果我弄错了,我会更新答案。 很好解释。帮助过我 !!谢谢【参考方案2】:

您将如何并行实现它?假设您有 4 个分区并且想要获取前 5 个元素。如果您事先知道每个分区的大小,这将很容易:例如,如果每个分区有 3 个元素,驱动程序会要求分区 0 获取所有元素,并要求分区 1 获取 2 个元素。所以问题是它知道每个分区有多少元素。

现在,您可以先计算分区大小,但这需要限制支持的 RDD 转换集、多次计算元素或进行其他权衡,并且通常需要更多的通信开销。

【讨论】:

我只是假设并行版本将在将来的某个时候实现,因为文档显示“当前未并行执行”。 正如我所说,可以进行权衡以允许(至少某些)并行性。据我所知,他们只是还没有决定制作哪一个(如果有的话)。 为什么不从每个分区中并行获取大致相等数量的行呢? Take() 不能保证它在移动到下一个分区之前用完所有分区,那么为什么要遵循这种方法呢? @max 它确实:“返回一个包含 first n 个元素的数组”。

以上是关于为啥 Apache Spark 的功能不并行?的主要内容,如果未能解决你的问题,请参考以下文章

Apache Spark:多机器学习算法的并行化

Spark 特性|深入研究 Apache Spark 3.0 的新功能

使用Apache Spark实现python功能

深入研究 Apache Spark 3.0 的新功能

Spark---Dataset

即将推出的Apache Spark 2.4有什么新功能