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

143 阅读5分钟

这是我参与「第四届青训营」笔记创作活动的的第13天,以下是我的课堂笔记。 本次课程主要分为四个大板块:
1.列存vs.行存
2.Parquet原理详解
3.ORC 详解和对比
4.列存演进

1.列存vs.行存

1.1数据格式层概述

√计算层:各种计算引擎
√存储层:承载数据的持久化存储
√数据格式层:定义了存储层文件内部的组织格式, 计算引擎通过格式层的支持来读写文件

image.png

1.2分层视角下的数据形态

·存储层:File,Blocks
·格式层:File内部的数据布局(Layout + Schema)
·计算引擎:Rows + Columns

image.png

1.3 两种数据查询分析场景:OLTP vs. OLAP

image.png

1.4 OLTP:行式存储格式(行存)

√每行的数据在文件上是连续存储的
√读取整行数据效率高,单次IO顺序读即可
√典型系统
·关系型数据库: MySQL,Oracle ...
. Key-Value数据库

1.5 OLAP:列式存储格式(列存)

√每列的数据在文件上是连续存储的
√读取整列的效率较高
√同列的数据类型—致,压缩编码的效率更好
√典型系统
·大数据分析系统:SQL-on-Hadoop,数据 湖分析
数据仓库: ClickHouse,Greenplum,阿里云MaxCompute

2.Parquet原理详解

2.1 Parquet简介

parquet.apache.org
√ 大数据分析领域使用最广的列存格式
√ Spark推荐存储格式

√Github
parquet-format:格式定义
parquet-mr : Java实现

image.png

2.2 Dremel数据模型

V Protocol Buffer定义
V支持可选和重复字段
V支持嵌套类型

image.png

2.3数据布局

.RowGroup:每一个行组包含一定数量或者固定大小的 行的集合
.ColumnChunk: RowGroup中按照列切分成多个ColumnChunk
. Page: ColumnChunk内部继续切分成Page,一般建 议8KB大小。压缩和编码的基本单元
·根据保存的数据类型分为:Data Page,Dictionary Page,Index Page
.Footer保存文件的元信息
.Schema
. Config
.Metadata
.RowGroup Meta
.Column Meta

image.png

2.4编码 Encoding

. Plain直接存储原始数据
. Run Length Encoding (RLE):适用于列基数不大,重复 值较多的场景,例如:Boolean、枚举、固定的选项等
. Bit-Pack Encoding:配合 RLE编码使用,让整形数 字存储的更加紧凑
. 字典编码 Dictionary Encoding:适用于列基数不大的场 景,构造字典表,写入到 Dictionary Page;把数据用字典Index替换,然后用RLE编码 image.png

2.5压缩Compression

.Page完成Encoding以后,进行压缩
·支持多种压缩算法
·snappy:压缩速度快,压缩比不高,适用于热数据
·gzip:压缩速度慢,压缩比高,适用于冷数据
·zstd:新引入的压缩算法,压缩比和gzip差不多,而且 压缩速度比肩Snappy
·建议选择snappy或者zstd,根据业务数据类型充分测试压缩效果,以及对查询性能的影响

image.png

2.6索引 Index

·和传统的数据库相比,索引支持非常简陋
·Min-Max Index:记录 Page内部Column的min_value和max_value
·Column Index:
. Footer 里的 Column Metadata包含 ColumnChunk的全部 Page的 Min-MaxValue
·Offset Index: 记录 Page在文件中的 Offset和Page的 Row Range

image.png

2.7过滤下推 Predicate PushDown

√parquet-mr 库实现,实现高效的过滤机制
√引擎侧传入Filter Expression
√parquet-mr转换成具体Column的条件匹配
√查询Footer 里的Column lndex,定位到具体的 行号
√返回有效的数据给引擎侧

image.png

2.8 Spark集成-向量化读

. ParquetFileFormat类
. 向量化读开关:
spark.sql.parquet.enableVectorizedReader·向量化读是主流大数据分析引擎的标准实践,可 以极大的提升查询性能
. Spark 以 Batch的方式从 Parquet读取数据, 下推的逻辑也会适配 Batch的方式

image.png

3. ORC详解

3.1 ORC简介

. orc.apache.org
. 大数据分析领域使用最广的列存格式之一
· 出自于Hive项目
· CREATE TABLE tabLe_name (xINT,y STRING)STORED AS ORC;

image.png

3.2数据模型

.ORC会给包括根节点在内的中间节点都创建一个 Column .下图中,会创建8个Column
.嵌套类型或者集合类型支持和Parquet差别较大
.optional和repeated字段依赖父节点记录额信 息来重新Assembly 数据

image.png

3.3数据布局

·类似 Parquet
.Rooter + Stripe + Column + Page (Row Group)结构
.Encoding / Compression / lndex支持上和Parquet几乎一致

image.png

3.4 ACID特性简介

√支持 Hive Transactions 实现,目前只有Hive本身集成
√类似 Delta Lake / Hudi / lceberg
√基于Base + Delta + Compaction的设计

image.png

3.5 AliORC

√ORC 在阿里云计算平台被广泛应用,主流产品MaxCompute +交互式分析Hologres的 最新版本都支持ORC格式
√AliORC是对ORC的深度定制版

3.6 Parquet vs.ORC对比

·从原理层面,最大的差别就是对于NestedType和复杂类型处理上
. Parquet的算法上要复杂很多,带来的CPU的开销比 ORC要略大
.ORC的算法上相对简单,但是要读取更多的数据
.因此,这个差异的对业务效果的影响,很难做一个定性的判定,更多的时候还是要取决于实 际的业务场景

4.列存演进

4.1数仓中的列存

. ClickHouse的MergeTree引擎也 是基于列存构建的
·默认情况下列按照Column拆分的
.支持更加丰富的索引
·湖仓—体的大趋势 image.png

4.2存储侧下推

.更多的下推工作下沉到存储服务侧
·越接近数据,下推过滤的效率越高
·例如AWS s3 Select功能
·挑战:
·存储侧感知Schema
·计算生态的兼容和集成 image.png

4.3 Column Family支持

·背景:Hudi数据湖场景下,支持部分列的快速更新
·在Parquet 格式里引入Column Family概念,把需 要更新的列拆成独立的Column Family
·深度改造Hudi的 Update和Query逻辑,根据 Column Family选择覆盖对应的 Column Family
·Update 操作实际效果有10+倍的提升

image.png