Apache parquet 和 arrow 的区别

Difference between Apache parquet and arrow

我正在寻找一种方法来加速我的内存密集型前端 vis 应用程序。我看到有人推荐 Apache Arrow,我正在研究它,我对 Parquet 和 Arrow 之间的区别感到困惑。

它们都是列式数据结构。本来以为parquet是针对磁盘的,arrow是针对内存格式的。但是,我刚刚了解到您也可以将箭头保存到办公桌上的文件中,例如 abc.arrow 那么,有什么区别呢?他们不是在做同样的事情吗?

Parquet 是一种用于数据序列化的列式文件格式。读取 Parquet 文件需要将其内容解压缩并解码为某种 in-memory 数据结构。它被设计为 space/IO-efficient,但以 CPU 的解码利用率为代价。它不为 in-memory 计算提供任何数据结构。 Parquet 是一种流格式,必须从 start-to-end 解码,而最近已将一些 "index page" 设施添加到存储格式中,通常随机访问操作的成本很高。

另一方面,Arrow 首先是一个为 in-memory 计算 提供柱状数据结构的库。读取Parquet文件时,可以将数据解压解码成Arrow列数据结构,然后对解码后的数据进行分析in-memory。 Arrow columnar format 有一些很好的特性:随机访问是 O(1) 并且每个值单元在内存中都紧挨着前一个和后一个,因此迭代是高效的。

那"Arrow files"呢? Apache Arrow 定义了一个二进制 "serialization" 协议,用于排列 Arrow 柱状数组(称为 "record batch")的集合,可用于消息传递和进程间通信。您可以将协议放在任何地方,包括磁盘上,稍后可以 memory-mapped 或读入内存并发送到其他地方。

此 Arrow 协议旨在让您可以 "map" 一大块 Arrow 数据而无需进行任何反序列化,因此对磁盘上的 Arrow 协议数据执行分析可以使用 memory-mapping 并有效地支付零成本.该协议用于许多事情,例如针对 Spark SQL 数据块的 运行 pandas 函数在 Spark SQL 和 Python 之间流式传输数据,这些是称为 "pandas udfs"。

在某些应用程序中,Parquet 和 Arrow 可以互换使用以进行 on-disk 数据序列化。一些注意事项:

  • Parquet 用于 "archival" 目的,这意味着如果您今天编写一个文件,我们预计任何自称可以 "read Parquet" 的系统将能够在 5 年或 7 年后读取该文件年。我们还没有对 Arrow 格式的 long-term 稳定性做出这种断言(尽管我们将来可能会)
  • Parquet 的读取成本通常要高得多,因为它必须解码为其他一些数据结构。 Arrow 协议数据可以简单地为 memory-mapped。
  • 由于 Parquet 使用的数据编码方案,Parquet 文件通常比 Arrow-protocol-on-disk 小得多。如果您的磁盘存储或网络速度较慢,Parquet 将是更好的选择

所以,综上所述,Parquet文件是为磁盘存储设计的,Arrow是为in-memory设计的(但你可以把它放在磁盘上,然后memory-map)。它们旨在相互兼容并在应用程序中一起使用。

对于 memory-intensive 前端应用程序,我可能建议查看 Arrow JavaScript (TypeScript) 库。