数据和文件格式架构师指南
数据世界正在发生一场革命。在技术进步的推动下,当前的开源数据格式浪潮正在改变整个生态系统的游戏规则——从供应商到企业。
数据需要组织和分析以生成及时的见解,以帮助公司做出更好的决策并改善运营。处理图像、.pdf、音频、视频等非结构化数据会带来不同的挑战。CSV、XML、JSON 等结构化和半结构化数据难以压缩、优化和长期存储。
从这些数据集中生成见解的能力取决于数据的组织方式。由于企业正在记录的业务数据越来越复杂,他们可能会发现,他们现在不是为每个数据事件收集 20 个字段,而是捕获数百个字段。虽然这些数据很容易存储在数据湖中,但如果以基于行的格式存储,查询它就需要扫描大量数据。
通过数据处理、人工智能/机器学习 (AI/ML)、商业智能和报告工作负载查询和操作数据的能力变得至关重要。这些工作负载总是需要从庞大的数据集中获取小范围的数据。因此需要数据格式。
如果你接触过数据工程师,你一定听说过Parquet、ORC、Avro、Arrow、Protobuf、Thrift、MessagePack等不同的数据格式,这些文件和数据格式都有哪些?它们适用于哪些地方?如何为合适的工作选择合适的设计?这些是我们将在本文中破译的一些问题。
微服务的数据格式
在深入研究数据湖中高效存储和检索的数据格式之前,让我们看看与数据湖不太相关的布局。Protobuf、Thrift 和 MessagePack 等数据格式与微服务之间的相互通信更相关。
协议缓冲区
Google 的 Protocol Buffers(也称为 Protobuf)是一种与语言和平台无关的数据序列化格式,用于有效地编码结构化数据以通过网络传输或将其存储在文件中。它被设计为可扩展的,允许用户定义自己的数据类型和结构,并提供可以高效传输和存储的紧凑二进制表示。Protocol Buffers 在各种 Google API 中使用,并在许多编程语言中得到支持,包括 C++、Python 和 Java。Protocol Buffers常用于需要通过网络传输数据或以紧凑格式存储数据的情况,例如网络通信协议、数据存储和数据集成。
实施概览
gRPC 是一个现代的、开源的、高性能的 RPC(远程过程调用)框架,可以在任何环境中运行。它使客户端和服务器应用程序的方法直接交互,类似于面向对象编程中的方法调用。gRPC 建立在 HTTP/2 之上,作为传输协议和用于编码请求和响应消息的 ProtoBuf 框架。gRPC 旨在高效,支持双向流和低延迟通信,并且可以在任何环境中运行。它用于各种 Google API,并受多种编程语言支持,包括 C++、Python 和 Java。
gRPC 用于低延迟、高性能和高效通信很重要的各种上下文和应用程序。它通常用于连接多语言系统,例如连接移动设备、Web 客户端和后端服务。它还在微服务架构中用于连接服务和构建可扩展的分布式系统。此外,gRPC 还用于 IoT(物联网)应用程序、实时消息和流媒体以及连接云服务。

节约
另一种类似于 Protobuf 的数据格式是 Thrift。Thrift是一种接口定义语言 (IDL) 和通信协议,允许开发可跨多种编程语言使用的可扩展服务。它类似于其他 IDL,例如 CORBA 和 Google 的 Protocol Buffers,但设计为轻量级且易于使用。Thrift 使用代码生成方法,根据 IDL 定义为所需的编程语言生成代码,允许开发人员轻松构建可以使用 Thrift 的二进制通信协议相互通信的客户端和服务器应用程序。Thrift 用于各种应用程序,包括分布式系统、微服务和面向消息的中间件。
支持的语言
Apache Thrift 支持多种编程语言,包括 Erlang 和 Haskell 等函数式语言。这允许您用一种语言定义服务,然后使用 Thrift 生成必要的代码以用另一种语言实现服务,以及可用于从另一种语言调用服务的客户端库。这使得构建使用多种编程语言的互连系统成为可能。
实施概述
IDL 编译器生成的代码创建客户端和服务器存根,它们在底层通过本地协议和传输层在两者之间进行交互,从而在进程之间启用 RPC。

消息包
MessagePack 是一种数据序列化格式,它提供结构化数据的紧凑二进制表示。通过使用数据的二进制表示而不是基于文本的表示,它旨在比其他序列化格式(例如 JSON)更高效、更快速。MessagePack 可用于各种应用程序,包括分布式系统、微服务和数据存储。许多编程语言都支持它,包括 C++、Python 和 Java,并且通常用于需要通过网络传输数据或以紧凑格式存储数据的情况。MessagePack 除了效率和速度之外,还被设计成可扩展的,允许用户定义自己的数据类型和结构。
支持的语言
MessagePack 支持多种编程语言,主要归功于它的简单性。请参阅其门户网站上的实施列表。
实施概览
我们在MinIO决定使用MessagePack作为我们的序列化格式。它通过允许添加/删除键来保持 JSON 的可扩展性。初始实现是一个标头,后跟一个具有以下结构的 MessagePack 对象:
{
"Versions": [
{
"Type": 0, // Type of version, object with data or delete marker.
"V1Obj": { /* object data converted from previous versions */ },
"V2Obj": {
"VersionID": "", // Version ID for delete marker
"ModTime": "", // Object delete marker modified time
"PartNumbers": 0, // Part Numbers
"PartETags": [], // Part ETags
"MetaSys": {} // Custom metadata fields.
// More metadata
},
"DelObj": {
"VersionID": "", // Version ID for delete marker
"ModTime": "", // Object delete marker modified time
"MetaSys": {} // Delete marker metadata
}
}
]}元数据转换发生在以前的版本中,新版本包括“V2Obj”或“DelObj”,具体取决于收到更新请求时的活动操作。本质上,在我们只需要读取元数据的情况下,我们可以在到达元数据末尾时停止读取文件。我们最多可以通过两次连续读取来实现更新。
磁盘上的表示也被更改以适应这一点。以前,所有元数据都被存储为一个包含所有版本的大对象。现在,我们这样写:
带版本的签名
标头数据的一个版本(整数)
元数据的一个版本(整数)
版本计数(整数)

如果您想更好地了解此 MessagePack 的版本控制在 MinIO 中是如何工作的,请阅读这个优秀的博客。
流媒体数据格式
阿夫罗
Apache Avro 是一个数据序列化系统,它提供了数据结构的紧凑和快速的二进制表示。它被设计成可扩展的,允许用户定义他们自己的数据类型和结构,并提供对动态和静态类型语言的支持。Avro 常用于 Hadoop 生态系统中,用于各种应用,包括数据存储、数据交换和数据集成。Avro 使用基于模式的方法,其中为数据定义模式,并用于序列化和反序列化数据。这允许 Avro 支持丰富的数据结构和数据随时间的演变。Avro 还支持容器文件来存储持久数据、RPC 和与多种语言的集成。
Avro 依赖于模式。Avro 模式在写入 Avro 数据时保存在文件中。Avro 模式是一个 JSON 文档,它定义了存储在 Avro 文件中或在 Avro 消息中传输的数据的结构。它定义了数据中字段的数据类型,以及这些字段的名称和顺序。它还可以包括有关数据编码和压缩的信息,以及与数据关联的任何元数据。
Avro 模式用于确保以一致且可预测的格式存储和传输数据。当数据写入 Avro 文件或在 Avro 消息中传输时,模式包含在数据中,以便数据的接收者知道如何解释它。
模式方法允许序列化既小又快,同时支持动态脚本语言。
文件可以稍后由任何程序处理。如果读取数据的程序需要不同的模式,这可以快速解决,因为两种模式都存在。
支持的语言
Apache Avro 是领先的记录数据序列化格式,也是流数据管道的首选。它提供了出色的模式演变,并具有 JVM(Java、Kotlin、Scala 等)、Python、C/C++/C#、PHP、Ruby、Rust、JavaScript 甚至 Perl 的实现。
要了解更多关于 Avro 与其他系统的比较,请查看文档中的这个有用的比较。
Apache Kafka 和Confluent Platform为 Avro 建立了一些特殊的连接,但它适用于任何数据格式。

数据湖的大数据文件格式
镶木地板
Apache Parquet 是一种用于大数据处理的列式存储格式。它旨在高效地存储和处理,并作为数据存储和交换格式广泛应用于 Hadoop 生态系统。尽管 Hadoop 正在衰落,但该格式仍然具有相关性并得到广泛使用,部分原因是它得到了包括 Apache Spark、Apache Flink 和 Apache Drill 在内的关键数据处理系统的持续支持。
Parquet 以柱状格式存储数据,以针对过滤和聚合等列式操作优化的方式组织数据。Parquet 结合使用压缩和编码技术以高效方式存储数据,它允许创建可用于强制数据类型约束并实现快速数据处理的数据模式。Parquet 是存储和查询大型数据集的流行选择,因为它支持快速查询和高效的数据存储和处理。
实施概览
该模式允许有效地捕获元数据,支持文件格式的演变并简化数据存储。Parquet 压缩算法降低了存储需求,实现了更快的检索,并且得到了许多框架的支持。元数据分为三种类型:文件元数据、列(块)元数据和页眉元数据。Parquet 利用 Thrift 的 TCompactProtocol 对元数据结构进行序列化和反序列化。

兽人
ORC,或优化行列,是一种数据存储格式,旨在通过优化大量数据的存储和检索来提高数据处理系统(例如 Apache Hive 和 Apache Pig)的性能。ORC 以列格式存储数据,这意味着数据是按列而不是按行组织和存储的。这允许更快地查询和分析数据,因为只需要访问相关列而不是读取整行数据。ORC 还包括诸如压缩、谓词下推、为同一文件使用单独的 RecordReader 时改进的并发性以及类型推断等功能,以进一步提高性能。
与 RCFile 格式相比,ORC 的另一个改进领域,特别是在 Hadoop 部署中,是它大大减少了 NameNode 上的负载。
应该注意的是,ORC 已针对 Hadoop 架构和工作负载进行了调整。鉴于大多数现代数据堆栈正在远离 Hadoop,ORC 在云原生环境中的实用性有限。
实施概览
ORC 文件中的行数据被组织成称为条带的组,其中包含一系列行和关于这些行的元数据。每个条带包含一系列行,每行又分为一系列列。每列的数据都是单独存储的,这使得 ORC 可以高效地只读取特定查询所需的列,而不是读取整行。ORC 还包括有关数据的元数据,例如数据类型和压缩信息,这有助于提高读取性能。ORC 支持多种压缩格式,包括 zlib、LZO 和 Snappy,有助于减少磁盘数据的大小,提高读写性能。它还支持各种类型的索引,例如行索引和布隆过滤器,可用于进一步提高读取性能。

的输出orcfiledump包括文件元数据的摘要,例如文件中的行数、列数和条带数。它还包括列的数据类型和文件中存储的任何索引信息。
除了元数据之外,orcfiledump还打印 ORC 文件中的实际数据。这包括每一行中每一列的值,以及存在的任何 NULL 值。每行代表一条记录,它由定义为字段的每一列组成。行组合起来表示表格结构。
箭
Apache Arrow 相对较新,是一种开源的内存中柱状数据格式,旨在加速分析和数据处理任务。它是一种标准化格式,用于表示和操作各种系统中的数据,包括数据存储系统、数据处理框架和机器学习库。
Apache Arrow 的主要优势之一是它能够在不同系统和进程之间高效地传输数据。它允许在系统之间共享和交换数据,而不需要序列化或反序列化,这可能是耗时和资源密集型的。这使得它非常适合在需要快速处理和分析大量数据的分布式和并行计算环境中使用。
除了性能优势外,Apache Arrow 还具有丰富的功能集,包括对广泛数据类型的支持、对嵌套和分层数据结构的支持,以及与各种编程语言的集成。Arrow 格式通常用于大数据和分析应用程序,可用于在系统之间高效地传输数据并处理内存中的数据。它还用于分布式系统和实时分析管道的开发。
实施概述
大多数数据团队面临的挑战是,在没有标准列数据格式的情况下通过序列化/反序列化来处理每个数据库和语言的内部数据格式会导致效率低下和性能问题。另一个主要挑战是为每种数据格式编写标准算法,从而导致重复和膨胀。

Arrow 的内存中柱状数据格式通过减少对磁盘的 IO 读取和写入并启用查询加速来显着增强数据分析。它对数据使用固定宽度的二进制表示,允许在内存中快速读取和写入数据。除了通过内存计算改进运营工作外,该框架还允许添加自定义连接器以简化各种格式的数据聚合。

Dremio 是基于 Arrow 框架构建的查询加速工具。Dremio 旨在为各种数据源(如数据库、数据湖和云存储系统)提供快速查询性能。它使用 Arrow 内存中的列式数据格式来存储和处理数据,这使其能够利用 Arrow 的性能和效率优势。如需进一步阅读,请参阅“ Apache Arrow 及其如何适应当今的数据格局”。
课程的马匹——选择最好的形式
组织已投资于微服务架构以实现更好的软件管理,从而避免单一方法。采用容器化并部署在大型 Kubernetes 集群上是一种自然演变。这些微服务是用异构语言构建的,并采用了多语言多范式。
采用 Protocol Buffers、Thrift 或 MessagePack 在这些场景中很有帮助。它们简化了微服务之间的相互通信并实现了更快的事件处理。有助于提高应用程序可支持性的其他好处是独立和频繁部署的能力。
随着流媒体和消息驱动架构的出现,对数据格式和压缩的广泛需求将 Avro 推向了前沿。如上所述,Arvo 非常灵活,可以跨微服务、流应用程序和消息驱动架构采用,并在数据湖和湖屋架构中大量实施。Iceberg 和 Hudi 等开放表格式利用 Avro 和支持快照隔离的模式。
Parquet 在数据湖和湖屋架构方面处于领先地位,并且仍然是该领域的标准。ORC 支持大条带大小的能力使其在 Hadoop 分布式文件系统 (HDFS) 世界中得到广泛应用,但正如我们所知,这个世界正在缩小。尽管如此,它仍具有用于备份用例的实用程序。Arrow 是这个领域的新成员,它非常适合内存,并且可以用于对象持久性需求较短的对象存储用例。
结论
现代数据堆栈是一种选择,在数据和文件格式方面有越来越多的好选择。MinIO 支持所有这些,将选择权留给您和您的云架构师来决定使用哪个。通过在此处下载或查看我们的Slack 频道或通过商业许可直接与工程团队联系,随时使用 MinIO 试用它们。