parquet与orc对比

349 阅读3分钟

一、Parquet与ORC 核心特性对比

1. 文件组织形式

graph TD
    subgraph Parquet结构
        A[Parquet文件] --> B[行组 Row Group]
        B --> C[列块 Column Chunk]
        C --> D[页 Page]
        D --> D1[数据页]
        D --> D2[字典页]
        D --> D3[索引页]
    end

    subgraph ORC结构
        X[ORC文件] --> Y[条带 Stripe]
        Y --> Z[行组 Row Group]
        Y --> Z1[索引数据]
        Y --> Z2[流数据]
        Z2 --> Z21[PRESENT流]
        Z2 --> Z22[DATA流]
        Z2 --> Z23[LENGTH流]
    end

❶ Parquet关键结构

  • 行组(Row Group):逻辑上的行分割单元(默认128MB),独立压缩编码
  • 列块(Column Chunk):单个列在行组内的数据块
  • 页(Page):最小IO单元(默认1MB),包含页头+压缩数据

❷ ORC核心结构

  • 条带(Stripe):数据存储的基本单位(默认64MB),包含:
    • 行组(Row Group):条带内按行数分块(默认10,000行)
    • 索引数据:条带级的行组统计信息(min/max,布隆过滤器)
    • 数据流:分为PRESENT(存在位图)、DATA(实际数据)、LENGTH(变长类型)

2. Schema支持

特性ParquetORC
嵌套类型支持复杂嵌套(Group/List)支持STRUCT/MAP/LIST
数据类型更丰富的逻辑类型(DATE32等)类型系统相对简单
Schema演进支持列增删(向后兼容)需要严格兼容性(限制更多)

案例:Apache Spark读取Parquet时可自动处理新增列(Null填充旧数据),而ORC需要显式声明兼容模式。


3. 查询效率优化

xychart-beta
    title 查询效率对比(TPC-H Q1)
    x-axis ["全表扫描", "谓词过滤", "聚合查询"]
    y-axis "耗时 (ms)" [0, 5000]
    bar ["Parquet", 3200, 850, 1200]
    bar ["ORC", 2800, 600, 1500]
  • 向量化读取:ORC内置向量化优化(ORC Vectorization),比Parquet快15-20%
  • 谓词下推:ORC提供更丰富的统计信息(布隆过滤器),过滤效率更高
  • 延迟物化:Parquet的列剪裁更彻底,减少IO数据量

4. 压缩效率

压缩算法Parquet压缩率ORC压缩率压缩耗时比
SNAPPY3.2:13.5:1Parquet快15%
ZSTD4.8:15.1:1ORC快10%
GZIP5.1:15.5:1ORC快25%

技术原理:ORC的 Run-Length Encoding 对重复值压缩更高效(如状态字段),而Parquet的 字典编码 对高基数列更优。


5. 元数据管理

  • Parquet

    message FileMetaData {
      required string version          // 文件格式版本
      repeated SchemaElement schema    // Schema定义
      repeated RowGroup row_groups     // 行组元数据
      optional KeyValueMetadata metadata // 自定义KV
    }
    

    元数据存储在文件末尾,支持快速Schema校验。

  • ORC

     {
       "stripeStats": [{
         "colStats": [{
           "numberOfValues": 1024,
           "min": "2023-01-01",
           "max": "2023-12-31"
         }]
       }]
     }
    

    文件头尾均存储元数据,支持快速定位条带。


二、在 数据湖技术 中的应用

1. Hudi与存储格式

graph LR
    Hudi -->|写入| Parquet("Parquet文件")
    Hudi -->|增量日志| Avro("Avro文件")
    Hudi -->|元数据| .hoodie["Hudi元数据"]
  • 应用特性
    • 主数据:使用Parquet存储基础数据(高压缩比)
    • 增量文件:使用Avro记录变更(快速合并)
    • Merge-On-Read:查询时合并Parquet与Avro文件

2. Iceberg与存储格式

flowchart TD
    Iceberg -->|数据文件| A[Parquet/ORC]
    Iceberg -->|元数据| B["元数据JSON/AVRO"]
    Iceberg -->|清单| C["清单列表(Manifest List)"]
  • 设计选择
    • 默认Parquet:利用其嵌套数据优势处理复杂Schema
    • ORC可选:需要更高压缩率时使用
    • 隐藏分区:通过元数据层实现,与存储格式解耦

3. Paimon与存储格式

classDiagram
    class Paimon {
        +LSM树结构
        +主键更新支持
        +流批一体
    }
    Paimon --> Parquet : 基础文件格式
    Paimon --> ORC : 可选格式(实验性)
  • 核心机制
    • LSM分层存储:将Parquet文件组织为SSTable结构
    • ChangeLog生成:通过ORC存储增量变更实现高效CDC

三、未来发展方向

1. 存储格式创新

graph LR
    当前现状 --> 向量化存储 --> 云原生优化 --> 智能存储
  • 向量化存储:与Arrow格式深度集成,支持零反序列化
  • 云原生设计
    • 对象存储优化(如S3分段上传友好)
    • 延迟加载元数据(减少LIST操作成本)
  • 智能压缩:AI预测最佳压缩算法(按列动态选择Snappy/ZSTD)

2. 数据湖集成趋势

技术栈存储格式选择策略未来演进
HudiParquet为主,ORC逐步支持增量日志ORC化
Iceberg双格式自动转换智能格式推荐引擎
Paimon深度绑定Parquet原生列式日志支持

3. 硬件协同优化

  • GPU加速
    # 使用RAPIDS加速Parquet读取
    import cudf
    df = cudf.read_parquet("data.parquet") 
    
    NVIDIA与开源社区合作优化GPU解码
  • 持久内存:PMem-aware存储布局,减少SSD磨损

四、选型建议指南

flowchart TD
    A[需求分析] --> B{主要场景}
    B -->|复杂嵌套数据| C[Parquet]
    B -->|高压缩比需求| D[ORC]
    B -->|频繁Schema变更| E[Parquet]
    B -->|批量分析为主| D[ORC]
    B -->|实时更新场景| F[Parquet+Avro]

黄金法则

  • 数仓型数据湖(Iceberg)优先选择Parquet
  • 流式数据湖(Paimon)坚持Parquet基础格式
  • 混合负载场景:ORC用于历史数据分析,Parquet用于实时层

存储格式的演进将持续推动数据湖向 更高效、更智能、更云原生 的方向发展。未来可能出现统一元数据层下的多格式混合存储方案,实现"存储格式无感"的数据湖体验。