一、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支持
| 特性 | Parquet | ORC |
|---|---|---|
| 嵌套类型 | 支持复杂嵌套(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压缩率 | 压缩耗时比 |
|---|---|---|---|
| SNAPPY | 3.2:1 | 3.5:1 | Parquet快15% |
| ZSTD | 4.8:1 | 5.1:1 | ORC快10% |
| GZIP | 5.1:1 | 5.5:1 | ORC快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. 数据湖集成趋势
| 技术栈 | 存储格式选择策略 | 未来演进 |
|---|---|---|
| Hudi | Parquet为主,ORC逐步支持 | 增量日志ORC化 |
| Iceberg | 双格式自动转换 | 智能格式推荐引擎 |
| Paimon | 深度绑定Parquet | 原生列式日志支持 |
3. 硬件协同优化
- GPU加速:
NVIDIA与开源社区合作优化GPU解码# 使用RAPIDS加速Parquet读取 import cudf df = cudf.read_parquet("data.parquet") - 持久内存: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用于实时层
存储格式的演进将持续推动数据湖向 更高效、更智能、更云原生 的方向发展。未来可能出现统一元数据层下的多格式混合存储方案,实现"存储格式无感"的数据湖体验。