Parquet 与 ORC:高性能列式存储 | 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的的第15天
行存 vs 列存
数据格式层
- 数据格式层:定义了存储层文件内部的组织格式,计算引擎通过格式层的支持来读写文件
- 严格意义上,并不是一个独立的层级,而是运行在计算层的一个Library
OLTP vs OLAP
- OLTP 和 OLAP 作为数据查询和分析领域两个典型的系统类型,具有不同的业务特征,适配不同的业务场景
- 理解两者的区别可以帮助更好的理解行存和列存的设计背景
| OLTP | OLAP | |
|---|---|---|
| 典型场景 | 在线业务系统,例如:订单、交易、社交、评论等 | 数据仓库或者大数据分析系统,例如:决策分析、BI系统、推荐系统等 |
| 访问特征 | - 事务- 实时性- 低延时- 高并发- 高可用 | - 弱事务性- 近实时、离线分析- 大吞吐- 并发相对不高- 可用性可以有一定的妥协 |
| 数据模型特征 | - Schema 相对简单- 数据维度不多- 数据规模较小 | - Schema 复杂- 数据维度很多,几百个Column 很常见- 数据规模巨大 |
行式存储格式 (行存) 与 OLTP
- 每一行 (Row) 的数据在文件的数据空间里连续存放的
- 读取整行的效率比较高,一次顺序 IO 即可
- 在典型的 OLTP 型的分析和存储系统中应用广泛,例如:MySQL、Oracle、RocksDB 等
列式存储格式 (列存) 与 OLAP
- 每一列 (Column) 的数据在文件的数据空间里连续存放的
- 同列的数据类型一致,压缩编码的效率更好
- 在典型的 OLAP 型分析和存储系统中广泛应用,例如:
- 大数据分析系统:Hive、Spark,数据湖分析
- 数据仓库:ClickHouse,Greenplum,阿里云 MaxCompute
Parquet 详解
使用 Parquet
# Spark
df.write.parquet("/path/to/file.parquet")
df.write
.partitionBy(”col1")
.format("parquet")
.saveAsTable(”sometable")
val df = spark.read.parquet(”/path/to/file.parquet")
# Hive DDL
CREATE TABLE table_name (x INT, y STRING) STORED AS PARQUET;
Spark生成的文件会有.parquet后缀, Hive生成的文件没有
ORC 详解
数据模型
- ORC 会给包括根节点在内的中间节点都创建一个 Column
- 下图中,会创建 8 个 Column
- 嵌套类型或者集合类型支持和 Parquet 差别较大
- optional 和 repeated 字段依赖父节点记录额外信息来重新 Assembly 数据
Parquet vs ORC 对比
- 从原理层面,最大的差别就是对于 NestedType 和复杂类型处理上
- Parquet 的算法上要复杂很多,带来的 CPU 的开销比 ORC 要略大
- ORC 的算法上相对加单,但是要读取更多的数据
- 因此,这个差异的对业务效果的影响,很难做一个定性的判定,更多的时候还是要取决于实际的业务场景