这是我参与「第四届青训营」笔记创作活动的第十四天。
数据形态
- 存储层:File,Blocks
- 格式层:File内部的数据格式(Schema+Layout)
- 计算引擎:Rows,Columns
OLTP 行存
每一行的数据在文件上是连续存储的
读取整行数据效率高,单次IO顺序读即可
典型
- 关系型数据库:MySQL,Oracle等
- Key-Value数据库
OLAP 列存
每一列的数据在文件上是连续存储的
读取整列数据效率高;同列数据类型一致,压缩编码效率更高
- 大数据分析系统: SQL-on-Hadoop , 数据湖分析
- 数据仓库: ClickHouse,Greenplum ,阿里云MaxCompute
Parquet原理
数据布局
- RowGroup:每一个行组包含一定数量或者固定大小的行的集合
- ColumnChunk: RowGroup中按照列切分成多个ColumnChunk
- Page: ColumnChunk内部继续切分成Page,一般建议8KB大小。压缩和编码的基本单元根据保存的数据类型分为: Data Page,Dictionary Page,Index Page
- Footer保存文件的元信息
- Schema
- Config
- Metadata
- RowGroup Meta
- Column Meta
- RowGroup Meta
编码
- Plain,直接存储原始数据
- Run Length Encoding,列基数不大,重复值较多的场景如:bool类型,枚举,固定的选项等。Bit-Pack Encoding :配合RLE编码使用让整形数字存储的更加紧凑。
- 字典编码 Dictionary Encoding,构建字典表,写入Dictionary Page,用index替代数据,再用RLE。
压缩
先编码,再压缩
- snappy:压缩速度快,压缩比不高,适用于热数据
- gzip:压缩速度慢,压缩比高,适用于冷数据
- zstd:压缩速度比肩snappy,压缩比接近gzip
索引
- Min-Max Index:记录page内部的最值
- Column Index:Footer中的Column Metadata包含Columnchunk全部page的Min-Max Value
- Offset Index:记录Page在文件中的Offset和Page的Row Range
列基数较大或非排序列的过滤,Min-Max Index难以发挥作用 Bloom Filter
- 引入Bloom Filter加速过滤匹配判定
- 每个ColumnChunk的头部保存Bloom Filter数据
- Footer记录Bloom Filter的page offset
过滤下推
- parquet-mr库实现,实现高效的过滤机制
- 引擎侧传入Filter Expression
- parquet-mr转换成具体Column的条件匹配
- 查询Footer里的Column Index ,定位到具体的行号
- 返回有效的数据给引|擎侧
ORC
数据布局
与parquet相似;Rooter+Stripe+Column+Page(Row Group)结构
ACID
支持Hive Transactions实现,目前只有Hive集成
基于Base+Delta+Compaction的设计
AliORC
索引增强
支持Clusterd Index更快地进行主键查找 支持Bitmap Index更快地过滤;Roaring Bitmap;较稀疏的情况
小列聚合
减少小IO,将较小的列放置到一起
异步预取
将计算逻辑和数据读取并行化