常见问题解答
一般
什么是 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 应用程序可以调用 C 或 C++ 算法来处理源自 JVM 的数据。
项目状态
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 和 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 数据格式使用自己的表示形式来实现最佳访问和计算。