为什么选择 Parquet,以及它为何在 S3 上表现如此出色
内容提要
Parquet 是一种列式二进制文件格式,其元数据页脚包含所有列块的字节偏移和统计信息,配合 S3 的 HTTP 范围请求,可实现精准读取,仅下载所需数据。它支持列式压缩、统计剪枝和自描述特性,在对象存储上高效运行。Iceberg 等湖仓格式依赖它实现双层数据跳过,相比 CSV、Avro 等格式,Parquet 在分析场景中优势显著。
延伸解读
元数据页脚:S3 上高效查询的关键
Parquet 将元数据集中放在文件末尾的页脚中,包含每个列块的字节偏移和统计信息。这一设计使得通过 HTTP 范围请求可以只读取所需数据,而无需下载整个文件。S3 自 2006 年起就支持范围请求,与 Parquet 的页脚布局结合,让对象存储上的分析查询变得高效。若缺少这一设计,每次查询都需下载完整文件,湖仓架构将无法成立。
双层数据跳过:湖仓格式的基石
Iceberg、Delta Lake 等湖仓格式选择 Parquet 作为数据层,并在其上增加清单和事务日志。这形成了两层数据跳过机制:清单层根据文件级统计信息过滤文件,Parquet 页脚层再根据行组统计和字节偏移精确读取。两层都依赖 Parquet 内建的偏移和统计信息,使得查询只需处理少量数据,大幅提升性能。
格式对比:Parquet 与 Avro、ORC 的取舍
CSV/JSON 无类型、无压缩、无随机访问,不适合分析;Avro 行式存储,适合写入和传输,但无法跳过列;ORC 与 Parquet 技术相似,但生态落后。Parquet 凭借列式布局、压缩和统计剪枝,成为分析场景的首选。实际应用中,常以 Avro 用于写入,Parquet 用于读取分析,各取所长。
Q&A
Parquet 文件格式的核心特点是什么?
Parquet 是一种列式二进制文件格式,将数据按列存储,并包含一个元数据页脚,其中记录了所有列块的字节偏移和统计信息(如最小值、最大值、空值计数)。它支持列级压缩、统计剪枝和自描述特性,无需外部元数据即可读取。
为什么 Parquet 在 S3 上表现如此出色?
Parquet 在 S3 上表现出色的关键在于其页脚布局与 S3 支持的 HTTP 范围请求相结合。读取时,先通过 HEAD 请求获取文件大小,然后范围请求文件尾部解析页脚,利用页脚中的统计信息和字节偏移,仅下载需要的列块和行组,从而避免下载整个文件。这种精准读取模式依赖于 HTTP 范围请求、S3 的实现和 Parquet 的页脚设计三者缺一不可。
Parquet 的列式存储和压缩相比行式存储有哪些优势?
列式存储将同一列的数据连续存放,分析查询通常只涉及少数列,因此可以只读取所需列,减少 I/O。同时,列内相邻值相似度高,压缩效果更好,典型压缩比可达 5-10 倍甚至更高。而行式存储(如 CSV、Avro)需要读取整行数据,无法跳过无关列,压缩效率也较低。
Parquet 如何利用统计信息进行查询优化?
Parquet 在每个行组中存储最小值、最大值和空值计数等统计信息,并可选地包含页索引和布隆过滤器。查询引擎在执行 WHERE 子句时,会利用这些统计信息跳过不可能匹配的行组,从而减少需要读取的数据量。这种剪枝机制在文件级别和行组级别都能显著提升查询性能。
Parquet 与 Avro 在适用场景上有何区别?
Parquet 是列式存储,适合分析型查询,能高效跳过无关数据,常用于数据仓库和湖仓格式(如 Iceberg、Delta Lake)。Avro 是行式存储,适合写入密集和流式传输场景,如 Kafka 消息和 Iceberg/Delta 的清单文件,因为它支持强模式演化和紧凑的二进制格式。经验法则是:写入和传输用 Avro,读取和分析用 Parquet。
为什么 Iceberg 等湖仓格式选择 Parquet 作为数据层?
Iceberg、Delta Lake 等湖仓格式选择 Parquet 是因为它提供了文件级别的统计信息和字节偏移,使得它们可以在清单层(manifest)和文件层(footer)实现双层数据跳过。清单层通过文件级统计信息过滤掉大部分文件,文件层则利用 Parquet 的页脚统计和偏移精确读取所需数据。这种能力是湖仓架构高效查询的关键。
Parquet 与 ORC 相比,为什么 Parquet 更流行?
ORC 在技术上与 Parquet 类似,甚至在某些方面(如条纹统计和谓词下推)更精细,但 Parquet 赢得了生态系统的支持,被 Spark、AWS 和更广泛的云生态采用,而 ORC 主要停留在 Hive/Hortonworks 生态中。因此,Parquet 成为更普遍的选择。