一、前言
Parquet和ORC作为Hive存储的两种重要文件格式,拥有众多优点,譬如压缩性能高,格式灵活,甚至支持部分算子下推的功能;为了解其背后实现的原理,今天特地进行部分整理
二、基本概念
- 行组(Row Group):一定数量的Row(默认Parquet的行组与HDFS的Block块对齐,所以一个行组默认被一个Mapper处理,拥有一个并发度)
- 列块(Column Chunk): 行组中的一列数据
- 页(Page):列块中的部分数据,编码的最小单位 参考官网的图片:
一个File包含多个Row Group,一个Row Group包含多个 Column Chunk,一个Column Chunk 包含多个页;
三、Dremel 编码解码算法
3.1 嵌套类型的数据模型
如下图所示,定义了一个张报表,报表又包含多个图表;
message Report {
required string owner;
repeated string phoneNumber;
repeated group Chart {
required int64 code;
optional String data;
}
}
-
每一个字段都有三个属性描述, repeated, 数据类型(group:复杂类型; primitive:基本类型), optional(出现0次或1次)
-
在Parquet格式的存储中,一个schema的树结构有几个叶子节点(叶子节点都是primitive type),实际的存储中就会有多少column。
3.2 Repetition levels
标志和与前一个节点共享的节点数,举例:
message nested {
repeated group leve1 {
repeated string leve2;
}
}
r1:[[a,b,c,] , [d,e,f,g]]
r2:[[h] , [i,j]]
计算repetition levels 的过程如下:
- value a 和之前的值在第0层是不共享的,所以 R = 0
- value b 和之前的值(a)在第2曾是是不同享的,所以R = 2
- c -> 2, d -> 1, e -> 2, f -> 2, g -> 2, h -> 0, i -> 1, j -> 2 在顺序读取每一个值的时候,可以根据repetition level创建对象,当R= 0时,新创建一个对象,当R= 1时,新创建一个level= 1的对象
3.3 Definition Levels
definition Level是路径上定义的repeated field 和 optional field的个数,不包括required field,因为required field是必须有定义的。需要的原因是由于存在Optional类型的字段,我们需要记录那些不存在的值;
3.3 举例说明
参考网上的一个例子:
上图左标识两条数据,右图表示列式存储保存的数据;
- 左图 -> 右图 根据定义对每一个对象执行即可得到每一个值的R和D
- 右图 -> 左图 可以将每一列都单独执行操作,R决定在第几层创建新的对象,D决定当前值放在第几层,比如第二个Name.Url的R= 1,D= 2,表示在对象的第一层上开始创建,并且创建知道直到 D= 2停止;
五、文件元数据和谓词下推
文件中有三种类型元数据:文件元数据、列块元数据、page元数据;
- 文件元数据包括:version, schema, 数据行数, 时间搓...
- 列块元数据
- 数据类型、压缩/非压缩大小, count数,编解码方式、...
- 统计量:min,max,distinct
- min/max/bloom过滤器
- 页元数据
- 存储信息:比如编码解码方式,crc校验,压缩字典等
- min/max
老版本的parquet只能通过列块信息进行将数据过滤,新版的parquet支持通过page的元数据过滤;当上层应用在查询parquet的数据文件时,可以通过扫描数据中的元数据信息,快速过滤数据,起到类似谓词下推到数据源的作用;