在 Spark 中构建的数据管道中,Apache 箭头的常见用例是什么

What is a common use case for Apache arrow in a data pipeline built in Spark

Apache Arrow 的用途是什么?它可以从一种二进制格式转换为另一种二进制格式,但我为什么需要它?如果我有一个 spark 程序,那么 spark 可以读取 parquet,那么为什么我需要在处理中途将它转换成另一种格式? 是否将内存中的数据传递给另一种语言,如 python 或 java 而不必将其写入 text/json 格式?

免责声明:这个问题很宽泛,我在某种程度上参与了 Apache Arrow 项目,所以我的回答 may/or 可能没有偏见。

这个问题很广泛,就像“我什么时候应该使用 NoSQL?”这样的问题。问题类型广泛。这取决于。 此答案基于您已经拥有 Spark 管道的假设。这个答案不是对 Spark Vs 的尝试。箭头(更宽到我不会碰它的程度)。

许多 Apache Spark 管道永远不需要使用 Arrow。与基于 Arrow 的管道不同,Spark 有自己的内存数据帧格式 (https://spark.apache.org/docs/1.6.1/api/java/org/apache/spark/sql/DataFrame.html),据我所知,它不能零复制到 Arrow。因此,从一种格式转换为另一种格式可能会带来某种性能影响,您获得的任何好处都必须权衡这一点。

你举了一个很好的例子,就是切换到其他语言/库。例如,Spark 目前使用 Arrow 来应用 Pandas UDF (https://spark.apache.org/docs/latest/api/python/user_guide/arrow_pandas.html)。在这种情况下,无论何时你要去一个不使用 Spark 内存格式的库(这意味着任何非 Java 库和一些 Java 库)你都必须做一个内存格式之间的转换,因此您无论如何都要付出性能损失,您不妨切换到 Arrow。

Arrow 的格式在某些方面比 Spark 的格式更快。我不打算在这里列出这些,因为在大多数情况下,收益不会超过首先使用 Spark -> Arrow 的成本,而且我不知道我有足够的信息来以任何一种全面的方式这样做。相反,我将提供一个具体示例:

Arrow 的一个常见情况是当您需要在同一台机器上的进程之间传输 table(或者它们之间有非常快的 I/O 通道)。在这种情况下,序列化为 parquet 然后反序列化的成本(Spark 必须执行此操作才能进入 Spark Dataframe -> Parquet -> Wire -> Parquet -> Spark Dataframe)比保存的 I/O 更昂贵(Parquet 是比 Spark Dataframe 更紧凑,因此您将在传输中节省一些)。如果您有很多此类通信,离开 Spark 可能会有所帮助,在 Arrow 中进行这些传输,然后 return 到 Spark。