Parquet 与 ORC:高性能列式存储

330 阅读2分钟

Parquet 与 ORC:高性能列式存储 | 青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第15天

行存 vs 列存

数据格式层

  • 数据格式层:定义了存储层文件内部的组织格式,计算引擎通过格式层的支持来读写文件
  • 严格意义上,并不是一个独立的层级,而是运行在计算层的一个Library

OLTP vs OLAP

  • OLTP 和 OLAP 作为数据查询和分析领域两个典型的系统类型,具有不同的业务特征,适配不同的业务场景
  • 理解两者的区别可以帮助更好的理解行存和列存的设计背景
OLTPOLAP
典型场景在线业务系统,例如:订单、交易、社交、评论等数据仓库或者大数据分析系统,例如:决策分析、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 的算法上相对加单,但是要读取更多的数据
  • 因此,这个差异的对业务效果的影响,很难做一个定性的判定,更多的时候还是要取决于实际的业务场景