常见问题解答


一般性问题

什么是Apache Arrow

Apache Arrow 是一个多语言工具箱,用于构建处理和传输大型数据集的高性能应用程序。它旨在提高分析算法的性能以及在不同系统(或编程语言之间)移动数据的效率。

Apache Arrow 的一个关键组成部分是其内存列式格式,这是一个标准化的、与语言无关的规范,用于在内存中表示结构化的、表格状的数据集。这种数据格式具有丰富的数据类型系统(包括嵌套和用户定义的数据类型),旨在满足分析数据库系统、数据框库等的需要。

该项目还包含许多语言的 Arrow 列式格式实现,以及用于将它们读写为许多常见存储格式的实用程序。这些官方库使第三方项目能够在不自己实现 Arrow 列式格式的情况下使用 Arrow 数据。对于那些想要实现格式的一小部分功能的人,Arrow 项目包含一些工具,例如 C 数据接口,以协助与官方 Arrow 库的互操作性。

Arrow 库包含许多软件组件,可协助解决与从远程存储系统获取数据和将数据通过网络接口传输有关的系统问题。即使在根本不使用列式格式的情况下,其中一些组件也可以使用。

最后,除了有助于数据访问和 I/O 相关问题的软件之外,还有用于针对 Arrow 数据集执行分析操作或查询的库。

为什么要为内存中的列式格式定义标准?

传统上,数据处理引擎的开发人员会创建自定义数据结构来在处理过程中表示内存中的数据集。鉴于这些数据结构的“自定义”特性,它们还必须开发序列化接口,以便在这些数据结构与不同的文件格式、网络传输协议、数据库客户端和其他数据传输接口之间进行转换。最终结果是开发人员时间和 CPU 周期在将数据从一种格式序列化到另一种格式上造成了巨大的浪费。

Arrow 的内存列式数据格式的原理是为几个相互关联的问题提供一个开箱即用的解决方案

  • 一种通用的表格数据表示形式,在现代硬件上处理效率高,同时适用于广泛的用例。我们相信,越来越少的系统会创建自己的数据结构,而会简单地使用 Arrow。
  • 支持随机访问和基于流/扫描的工作负载。
  • 标准化的内存格式有助于算法库的重用。当使用自定义内存数据格式时,常见的算法通常必须重写才能针对这些自定义数据格式。
  • 使用或支持 Arrow 的系统可以以几乎零成本在它们之间传输数据。这使得在分析工作负载中的序列化开销(这部分开销通常占计算成本的 80-90%)大大减少。
  • Arrow 格式的语言无关设计使得用不同编程语言编写的系统(即使是运行在 JVM 上的系统)能够在没有序列化开销的情况下通信数据集。例如,Java 应用程序可以对源自 JVM 的数据调用 C 或 C++ 算法。

项目状态

Arrow 格式的稳定性如何?在我的应用程序中使用它是安全的吗?

Arrow 列式格式和协议被认为是稳定的,我们打算只进行向后兼容的更改,例如添加数据类型。它已经被许多应用程序使用,您可以相信兼容性不会被破坏。有关 Arrow 格式版本控制和稳定性的详细信息,请参阅文档

Arrow 库的稳定性如何?

我们请您参考实现矩阵

Arrow 数据的 MIME 类型(IANA 媒体类型)

Apache Arrow IPC 协议数据(流和文件两种变体)已注册了官方 IANA 媒体类型(MIME 类型)

我们推荐使用 ".arrow" 作为 IPC 文件格式的文件扩展名

以及使用 ".arrows" 作为 IPC 流格式的文件扩展名


入门指南

在哪里可以获取 Arrow 库?

许多语言的 Arrow 库可通过常规的包管理器获得。有关详细信息,请参阅安装页面。


参与贡献

我有一些问题。如何获得帮助?

Arrow 邮件列表是提出问题的最佳场所。不要害羞——我们在这里提供帮助。

我尝试使用 Arrow 但它不起作用。你能修复它吗?

希望如此!请提交一份详细的错误报告——这对项目本身是一项宝贵的贡献。有关如何提交报告,请参阅贡献指南

Arrow 看起来很棒,如果它能做 X 我就会用它。它什么时候能完成?

我们使用GitHub作为我们的问题跟踪器。搜索一个符合您需求的问题。如果您找到了,请随时发表评论并描述您的用例——这将帮助接手该任务的人。如果您没有找到,请创建一个。

归根结底,Arrow 是由社区为社区编写的软件。如果您没有看到社区中的其他人正在处理您的问题,完成它的最佳方法就是自己动手贡献。我们非常乐意帮助您成功地为项目做出贡献。

如何报告安全漏洞?

请发送电子邮件至private@arrow.apache.org。有关更多信息,请参阅安全页面。


与其他项目的关系

Apache Arrow 和 Apache Parquet 有什么区别?

Parquet 不是“运行时内存格式”;通常,文件格式几乎总是在处理时需要反序列化到某种内存数据结构中。我们的目标是让 Arrow 成为这种内存中的数据结构。

Parquet 是一种存储格式,旨在实现最大的空间效率,使用先进的压缩和编码技术。当您希望最小化磁盘使用量并存储数 GB 或更多数据时,它是理想的选择。这种效率是以读取到内存的成本相对昂贵为代价的,因为 Parquet 数据不能直接操作,而必须大块解码。

相反,Arrow 是一种内存格式,主要用于直接且高效地用于计算目的。Arrow 数据通常不被压缩,而是以适合 CPU 的自然格式布局,以便数据可以以全速在任意位置被访问。(然而,Arrow 确实提供了一套有限的选项来提高空间效率,包括字典编码、运行结束编码和缓冲区压缩。)

因此,Arrow 和 Parquet 相互补充,并且通常在应用程序中一起使用。使用 Parquet 在磁盘上存储数据,然后以 Arrow 格式读取到内存中,将使您能够充分利用您的计算硬件。

那么“Arrow 文件”呢?

Apache Arrow 定义了一种进程间通信 (IPC) 机制,用于传输一组 Arrow 列式数组(称为“记录批次”)。它可以通过使用 Arrow 的“流格式”在进程之间同步使用,或者通过首先将数据持久化到存储中的 Arrow 的“文件格式”来异步使用。

Arrow IPC 机制基于 Arrow 内存格式,因此在磁盘表示和内存表示之间无需进行转换。因此,对 Arrow IPC 文件执行分析可以使用内存映射,从而避免任何反序列化成本和额外的复制。

在比较 Arrow IPC 文件格式和 Parquet 格式时需要注意的一些事项

  • Parquet 专为长期存储和存档目的而设计,这意味着如果您今天写入一个文件,您可以期望任何声称可以“读取 Parquet”的系统都可以在 5 年或 10 年后读取该文件。虽然 Arrow 的磁盘格式是稳定的,并且可以被未来版本的库读取,但它并不优先考虑长期存档存储的要求。

  • 读取 Parquet 文件通常需要高效但相对复杂的解码,而读取 Arrow IPC 文件不需要任何解码,因为磁盘表示与内存表示相同。

  • Parquet 文件通常比 Arrow IPC 文件小得多,这是因为 Parquet 使用的列式数据压缩策略。如果您的磁盘存储或网络速度慢,即使对于短期存储或缓存,Parquet 可能也是更好的选择。

“Feather”文件格式怎么样?

Feather v1 格式是在 Arrow IPC 文件格式开发之前,用于将 Arrow 格式的子集写入磁盘的简化自定义容器。“Feather version 2”现在完全是 Arrow IPC 文件格式,我们保留了“Feather”名称和 API 以保持向后兼容性。

Arrow 与 Protobuf 有何关系?

Google 的协议缓冲区库 (Protobuf) 不是“运行时内存格式”。与 Parquet 类似,Protobuf 的表示不适合处理。数据必须反序列化到像 Arrow 这样的内存表示中才能进行处理。

例如,Protobuf 中的无符号整数被编码为 varint,其中每个整数可能具有不同数量的字节,最后三位包含字段的线类型。您不能使用 CPU 以这种格式对数字求和。

Protobuf 有用于执行此反序列化的库,但它们不以通用的内存格式为目标。由 protoc 生成的 C# 代码反序列化的消息,其表示将与由 protoc 生成的 Java 代码反序列化的消息不同。您需要将数据从一种语言封送到另一种语言。

Arrow 避免了这种情况,但这会增加空间成本。Protobuf 在在线传输某些类型的数据(例如单个记录或具有许多可选字段的稀疏数据)时可能是更好的选择。就像 Parquet 一样,这意味着 Arrow 和 Protobuf 可以很好地互补。例如,Arrow Flight 使用 gRPC 和 Protobuf 来序列化其命令,而数据使用二进制 Arrow IPC 协议进行序列化。

Arrow 与 Flatbuffers 有何关系?

Flatbuffers 是二进制数据序列化的底层构建块。它不适用于表示大型、结构化、同质化数据,也不处于数据分析任务所需的正确抽象层面上。

Arrow 是一个数据层,直接面向数据分析的需求,提供了一套全面的数据类型以满足分析需求,内置对“null”值(表示缺失数据)的支持,以及一个不断扩展的 I/O 和计算工具箱。

Arrow 文件格式在底层确实使用了 Flatbuffers 来序列化实现 Arrow 二进制 IPC 协议所需的模式和其他元数据,但 Arrow 数据格式使用其自己的表示形式来实现最佳访问和计算。