深入了解Parquet格式及其优势

Parquet 是一种在现代大数据生态系统中极为流行的列式存储文件格式。它被设计用来高效地存储和处理大规模数据集。

核心思想:列式存储 vs 行式存储

要理解 Parquet 的优势,首先要明白它与传统行式存储(如 CSV、Avro)的区别。

特性行式存储列式存储
存储方式将一行的所有数据连续存储。
[Row1: A1, B1, C1], [Row2: A2, B2, C2], ...
将每一列的所有数据连续存储。
[Column A: A1, A2, A3, ...], [Column B: B1, B2, B3, ...]
适合场景OLTP 事务处理,需要频繁插入、更新、读取整行数据的场景。OLAP 分析处理,需要读取大量数据但只关心少数几列进行聚合、过滤的场景。
例子CSV, JSON, AvroParquet, ORC
读取模式读取时需要扫描所有列,即使只用到其中几列。可以只读取查询所需的列,跳过其他列,极大减少 I/O。
压缩效率一般。因为同一行中不同列的数据类型差异大,压缩效果有限。极高。因为同一列的数据类型相同,值通常相似,更容易获得高压缩比。

一个简单的比喻:

  • 行式存储 像是一本电话簿,每个人的所有信息(姓名、电话、地址)都在一起。
  • 列式存储 像是把所有姓名放在一个文件,所有电话放在另一个文件,所有地址放在第三个文件。

Parquet 的核心特性与优势

  1. 极高的查询性能

    • 列裁剪: 当你的查询只需要 SELECT user_id, timestamp 时,Parquet 读取器只会从磁盘上读取 user_idtimestamp 这两列的数据,完全跳过其他列(如 email, ip_address 等)。这大大减少了磁盘 I/O,是性能提升的关键。
  2. 高效的压缩和编码

    • 由于同一列的数据类型相同,Parquet 可以使用针对该类型优化的编码方式(如字典编码、游程编码、Delta 编码)。
    • 编码后的数据再进行压缩(如 Snappy, GZIP, LZ4),压缩比非常高,通常可以将数据缩小到原来的 1/4 到 1/10。这进一步减少了存储成本和 I/O 开销。
  3. 灵活的架构和强大的类型系统

    • Parquet 文件内置了 Schema(模式),描述了数据的结构、数据类型和嵌套关系。
    • 它支持复杂的嵌套数据结构(如数组、映射、结构体),通过 DLP(Dremel 的嵌套列存储算法) 将其高效地展平为列式存储。这使得它非常适合存储来自 JSON、Protocol Buffers 等半结构化数据。
  4. 谓词下推

    • 这是一个非常强大的优化技术。Parquet 文件为每个数据块存储了统计信息(如某列的最小值、最大值)。
    • 当执行一个带过滤条件的查询时(如 WHERE age > 30),查询引擎可以在实际读取数据之前,先检查这些统计信息。如果发现某个数据块的最大 age 是 25,那么整个数据块都会被跳过,根本不会被加载到内存中。
  5. 与大数据生态无缝集成

    • Parquet 是 Apache Hadoop、Spark、Flink、Hive、Impala、Presto/Trino 等主流大数据处理框架的首选文件格式。这些框架都对 Parquet 提供了原生、高度优化的支持。

Parquet 的文件结构

一个 Parquet 文件在物理上是由多个部分组成的:

  • 行组: 文件被水平分割成多个行组。每个行组包含数据的一个子集。
  • 列块: 在一个行组内,数据被垂直分割成列块。每个列块包含某一列的数据。
  • : 列块又被分成一系列的页。页是编码、压缩和访问的最小单元。常见的页类型有数据页、字典页等。
  • 页头: 包含页的元数据,如编码、压缩、未压缩大小等。
  • Footer(文件页脚): 这是文件的“目录”,包含至关重要的元信息:
    • File MetaData: 文件的 Schema。
    • RowGroup MetaData: 每个行组的信息,以及每个列块的统计信息(最小值、最大值、空值数量等),这些正是谓词下推的基础。
+---------------------------------------+
|  Magic Number "PAR1" (4 bytes)        |
+---------------------------------------+
|  Row Group 1                          |
|  +---------------------------------+  |
|  |  Column A Chunk (Pages)         |  |
|  +---------------------------------+  |
|  |  Column B Chunk (Pages)         |  |
|  +---------------------------------+  |
|  |  ...                            |  |
|  +---------------------------------+  |
+---------------------------------------+
|  Row Group 2                          |
|  +---------------------------------+  |
|  |  Column A Chunk (Pages)         |  |
|  +---------------------------------+  |
|  |  ...                            |  |
|  +---------------------------------+  |
+---------------------------------------+
|  ... (More Row Groups)               |
+---------------------------------------+
|  Footer (Metadata)                   |
|  +---------------------------------+  |
|  | Schema, Row Groups, Statistics |  |
+---------------------------------------+
|  Footer Length (4 bytes)             |
+---------------------------------------+
|  Magic Number "PAR1" (4 bytes)        |
+---------------------------------------+

何时使用 Parquet?

强烈推荐在以下场景使用:

  • 数据仓库和数据分析: 这是 Parquet 的主场,特别是当你需要频繁地对大型数据集进行聚合、过滤和扫描时。
  • 数据湖存储: Parquet 是数据湖(如 AWS S3, ADLS)中事实上的标准存储格式。
  • 作为 ETL 过程的中间格式或最终输出
  • 需要长期归档大量数据,以节省存储成本。

可能不适合的场景:

  • 需要频繁进行单行读写或更新的 OLTP 场景
  • 需要流式写入: Parquet 是为批量写入优化的,不适合一条一条地实时写入。
  • 数据量非常小: 对于小文件,Parquet 的元数据开销可能抵消其优势。

一个简单的代码示例(使用 PySpark)

# 读取 CSV 文件(行式)
df = spark.read.csv("path/to/large_file.csv", header=True, inferSchema=True)

# 将其保存为 Parquet 格式(列式)
df.write.parquet("path/to/output_parquet")

# 读取 Parquet 文件
df_parquet = spark.read.parquet("path/to/output_parquet")

# 执行一个只查询特定列的查询,Parquet 的列裁剪会生效
result = df_parquet.select("user_id", "timestamp").where(df_parquet.age > 30)
result.show()

总结

特性描述带来的好处
列式存储按列而非按行存储数据。查询性能快(列裁剪),压缩效率高
丰富的元数据文件内包含 Schema 和列块统计信息。谓词下推,跳过无关数据。
高效的编码针对不同数据类型使用特定编码。更高的压缩比,更快的扫描速度。
开源与通用被所有主流大数据工具支持。生态系统兼容性好,无供应商锁定。

总而言之,Parquet 是大数据分析和数据湖领域不可或缺的基石技术。如果你在处理 TB/PB 级别的数据,并专注于分析型工作负载,选择 Parquet 几乎总是一个正确的决定。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

走过冬季

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值