parquet文件格式解析

参考资料:
https://parquet.apache.org/documentation/latest/
https://www.jianshu.com/p/47b39ae336d5

前言

Apache Parquet是Hadoop生态系统中任何项目均可使用的列式存储格式,由于OLAP场景下的数据大部分情况下都是批量导入,基本上不需要支持单条记录的增删改操作,而查询的时候大多数都是只使用部分列进行过滤、聚合,所以列式存储在这种场景下效率很高

原理解析

1、名词解释

File:hdfs文件,必须包含该文件的元数据。

Row group(行组):对数据进行水平的划分分区,不保证其数据结构。行组有一定的行数,一个行组包含这个行组对应的区间内的所有列的列块。

Column chunk (列块):在一个行组中每一列保存在一个列块中,行组中的所有列连续的存储在这个行组文件中。并且数据保证在文件中是连续的。

page(页):每一个列块划分为多个页,页面是不可分割的单元(就压缩和编码而言)。列块中可以插入多种页面类型。

从层次上讲,文件由一个或多个行组组成。行组每列仅包含一个列块。列块包含一个或多个page。

2、具体结构

parquet文件格式解析
如上面所示 一个fILE包含多个行组,一个行组中包含多个列块,一个列块中包含多个page。
元数据包含着对于file文件中的行组和列快的一些信息,包含偏移量,基本类型等

元数据和data 是分开的,这样允许单个元数据文件引用多个parquet file。

2、读取计算过程

在读取数据的时候,我们可以看到上面结构图,元数据还存有着偏移量,num values等信息,比如我们在统计列行数以及max 等专门对列的操作的话,读取元数据,然后根据元数据寻找指定的列块进行读取计算,这样就大大提高了效率。

列式存储的优势

列式存储可以大大提升这类查询的性能,较之于行是存储,列式存储能够带来这些优化:

1、查询的时候不需要扫描全部的数据,而只需要读取每次查询涉及的列,这样可以将I/O消耗降低N倍,另外可以保存每一列的统计信息(min、max、sum等),实现部分的谓词下推。
2、由于每一列的成员都是同构的,可以针对不同的数据类型使用更高效的数据压缩算法,进一步减小I/O。
3、由于每一列的成员的同构性,可以使用更加适合CPU pipeline的编码方式,减小CPU的缓存失效。

实际应用

我们在做BI的时候用的时候用的sparkThriftserver,刚开始表存储是用的CSV格式,后续为了提升效率用的CSV,提升了效率大约2,3倍,而且存储空间也减少了很多。不过hive和sparkThriftserver,spark 也完美兼容parquet,在日常应用中来提升效率。