常见问题
概览
什么是 Apache Arrow?
Apache Arrow 是一个软件开发平台,用于构建处理和传输大型数据集的高性能应用程序。它的设计目标是提高分析算法的性能和将数据从一个系统(或编程语言)移动到另一个系统的效率。
Apache Arrow 的一个关键组件是它的内存列式格式,这是一种标准化的、与语言无关的规范,用于在内存中表示结构化的、类似表格的数据集。这种数据格式具有丰富的数据类型系统(包括嵌套和用户定义的数据类型),旨在支持分析数据库系统、数据框库等的需求。
该项目还包含多种语言的 Arrow 列式格式实现,以及用于读写多种常用存储格式的实用程序。这些官方库使第三方项目能够使用 Arrow 数据,而无需自行实现 Arrow 列式格式。对于那些只想实现格式一小部分的人来说,Arrow 项目包含一些工具,例如 C 数据接口,以帮助与官方 Arrow 库进行互操作。
Arrow 库包含许多软件组件,可帮助解决与将数据传入和传出远程存储系统以及通过网络接口移动 Arrow 格式数据相关的系统问题。即使在根本不使用列式格式的情况下,也可以使用其中一些组件。
最后,除了帮助解决数据访问和 IO 相关问题的软件之外,还有一些算法库,用于对 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 类型)
- https://www.iana.org/assignments/media-types/application/vnd.apache.arrow.stream
- https://www.iana.org/assignments/media-types/application/vnd.apache.arrow.file
我们建议使用“.arrow”作为 IPC 文件格式的文件扩展名
并使用“.arrows”作为 IPC 流格式的文件扩展名
入门
在哪里可以获得 Arrow 库?
许多语言的 Arrow 库都可以通过常用的包管理器获得。有关详细信息,请参阅安装页面。
参与进来
我有一些问题。我怎样才能获得帮助?
Arrow 邮件列表是提问的最佳场所。别害羞——我们随时为您提供帮助。
我尝试使用 Arrow,但它不起作用。你能解决这个问题吗?
希望如此!请提交详细的错误报告——这对项目本身来说是一项宝贵的贡献。有关如何提交报告,请参阅贡献指南。
Arrow 看起来很棒,如果它能做到 X,我肯定会使用它。什么时候可以完成?
我们使用GitHub作为我们的问题追踪器。搜索与您的需求匹配的问题。如果您找到了一个,请随时对其进行评论并描述您的用例——这将有助于任何接受该任务的人。如果您找不到,请创建一个。
最终,Arrow 是由社区编写并为社区服务的软件。如果您没有看到社区中的其他人正在处理您的问题,那么完成它的最佳方法就是亲自参与进来。我们非常愿意帮助您成功地为项目做出贡献。
如何报告安全漏洞?
请发送电子邮件至[email protected]。有关详细信息,请参阅安全页面。
与其他项目的关系
Apache Arrow 和 Apache Parquet 之间有什么区别?
Parquet 不是“运行时内存格式”;通常,文件格式几乎总是必须反序列化为某种内存数据结构才能进行处理。我们打算让 Arrow 成为那种内存数据结构。
Parquet 是一种存储格式,旨在最大限度地提高空间效率,使用高级压缩和编码技术。当您希望在存储千兆字节或更多数据时最大限度地减少磁盘使用量时,它是理想的选择。这种效率的代价是读取到内存中的成本相对较高,因为 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 使用的列式数据压缩策略,Parquet 文件通常比 Arrow IPC 文件小得多。如果您的磁盘存储或网络速度慢,即使是短期存储或缓存,Parquet 也可能是更好的选择。
那“Feather”文件格式呢?
Feather v1 格式是一种简化的自定义容器,用于在开发 Arrow IPC 文件格式之前将 Arrow 格式的子集写入磁盘。“Feather 版本 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 是一个直接针对数据分析需求的数据层,它提供了分析所需的全面数据类型集合、对“空”值(表示缺失数据)的内置支持,以及不断扩展的 I/O 和计算工具箱。
Arrow 文件格式确实在底层使用了 Flatbuffers 来序列化实现 Arrow 二进制 IPC 协议所需的模式和其他元数据,但 Arrow 数据格式使用其自身的表示形式来实现最佳访问和计算。