存储格式
问题
数据湖常用的文件格式有哪些?Parquet、ORC、Avro 如何选择?
答案
三大主流格式对比
| 维度 | Parquet | ORC | Avro |
|---|---|---|---|
| 存储方式 | 列式 | 列式 | 行式 |
| 压缩率 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| 查询性能 | 快(列裁剪) | 快(轻量索引) | 慢(全行扫描) |
| 嵌套结构 | ✅ 原生支持 | ⚠️ 有限 | ✅ 原生支持 |
| Schema 演进 | ✅ | ⚠️ 有限 | ✅ 强 |
| 写入速度 | 中 | 中 | 快 |
| 主要生态 | Spark、Iceberg | Hive | Kafka、序列化 |
Parquet 文件结构
Parquet 核心优势
- 列裁剪:只读取查询涉及的列
- 谓词下推:通过 Footer 中的 min/max 统计信息跳过不相关的 Row Group
- 嵌套结构:基于 Dremel 编码,支持复杂嵌套 JSON
选型建议
| 场景 | 推荐格式 | 理由 |
|---|---|---|
| OLAP 分析查询 | Parquet | 列裁剪 + 谓词下推 |
| Hive 数仓 | ORC | Hive 原生 + 索引 |
| Kafka 序列化 | Avro | 行式 + Schema Registry |
| 数据湖存储 | Parquet | Iceberg/Delta 默认格式 |
| ML 特征存储 | Parquet | Pandas/Spark 生态好 |
# Python 读写 Parquet 示例
import pandas as pd
# 写入 Parquet(自动列式 + 压缩)
df = pd.DataFrame({
'user_id': range(1000000),
'city': ['BJ', 'SH', 'GZ'] * 333333 + ['BJ'],
'amount': [100.5] * 1000000
})
df.to_parquet('events.parquet', compression='snappy')
# 只读取需要的列(列裁剪)
df_partial = pd.read_parquet('events.parquet', columns=['city', 'amount'])
常见面试问题
Q1: Parquet 和 CSV 相比有什么优势?
答案:
| 维度 | CSV | Parquet |
|---|---|---|
| 存储 | 文本,体积大 | 二进制列式,压缩 5~10x |
| Schema | 无 | 内嵌 Schema |
| 性能 | 全量扫描 | 列裁剪 + 谓词下推 |
| 类型 | 全当字符串 | 强类型 |
| 适用 | 数据交换 | 分析存储 |
Q2: 压缩算法如何选择?
答案:
- Snappy:压缩速度快,适合实时查询(Parquet 默认)
- ZSTD:压缩率高,适合存储优先场景
- LZ4:极快解压,适合计算密集型查询
- Gzip:压缩率最高,适合冷数据归档
相关链接
- 列式存储原理 - 列式存储深入理解
- Apache Iceberg - 基于 Parquet 的表格式
- Hive - ORC 文件格式的主要使用者