NightPxy 个人技术博客

Hadoop Parquet

Posted on By NightPxy

Parquet

概述

Parquet 是一种高性能的,与语言或平台无关的,列式存储格式.特别适合查询分析领域中

特性

自解析

Parquet 是一种带Schema信息的存储格式,存储数据会同时存储MetaData和SourceData(后面详解).这代表Parquet是能够自解析的,因此使用时无需手工构建Schema而非常方便

列式存储

Parquet 是一种列式存储的数据格式(后面详解).
这在OLAP查询中非常有用.

嵌套数据类型

通常使用类似关系型数据库,其数据类型都是扁平式的,诸如List,Map或者Struct之类复杂数据类型,是需要自行解析的.
Parquet支持嵌套数据类型,这意味着Parquet天然支持复杂数据类型

二进制文件

文件的实际存储数据为二进制形式,这代表人无法直接阅读

数据结构

文件结构 一个Parquet是由一个Header以及多个Block,以及一个foot结尾

  • Header存储的是一个4字节数字PAR1,用来校验文件是否是一个Parquet文件
  • Foot存储的是文件MetaData
    Footer length定义了MetaData的大小,可以据此读出整个MetaData部分的信息
    MetaData包含每一个行组的元数据信息和该文件存储数据的Schema信息
  • (一个或多个)Block块存储的是真正的数据

Block块结构 Block块内部有一个行组(RowGroup)结构概念,即Block内部由一个或多个行组组成
每个行组又由一组列块(Column chunk)组成的列数据,这就是列式存储中的按列集合存储了
每个列块内部又包含Page列表,包括数据页,字典页和索引页

  • 字典页 存储该列值的编码字典(每个列块有且仅有一个)
  • 数据页 存储当前行组中该列的值(这个值是字典页列值编码字典中的编码值)
  • 索引页 存储列块的统计信息

写入与读取

写入
当写入Parquet文件时,它会自动基于column的类型在列块字典页适配一个合适的编码,再保存编码值到数据页中,如果列值重复,将只是重复编码而不是重复列值
这代表就算是非压缩情况下的对等存储,Parquet本身就会普通文件更小,数据重复率越高,这种减少就越夸张,配合列式存储的同构数据的高重复率,Parquet的压缩比是非常高的

读取
读取一个Parquet文件时,需要完全读取Footer的meatadata和部分或者全部列块中的部分或全部页
Parquet不需要类似SequenceFile之类的游标跳跃检索,而是直接定位到block的边界,因为所有block的边界都存储于footer的metadata中(因为metadata的写入是在所有blocks块写入完成之后的,所以metadata始终持有每个block的位置)
而在读取块时,又会根据页统计信息,读取或跳过部分页

优缺点

优点

  • 列裁剪的完美支持
    列式存储数据,带来查询部分列时,可以完全跳过忽略的列的全部数据,
  • 自带谓词下推
    对每一个RowGroup,Parquet都会统计一些基本信息,这代表执行查询谓词时,可以根据直接读取统计信息,或根据统计信息,大幅跳过RowGroup读取
  • 高压缩比
    相同的列,往往是相同的数据结构或者高重复的几率,而列式存储将按列存储存储数据,这代表在压缩的时候,可以带来非常高的压缩比提升
  • Spark的完美支持
    Spark的默认数据类型就是Parquet,在很多方面,Spark都给与Parquet最高规格的支持,所以如果是以Spark为核心打造的计算集群,Parquet是首选.

缺点

  • 无法直接阅读
    因为其二进制存储的特性,无法直接阅读.
  • 查询需要二次组装.
    列式存储意味着需要二次组装列成为最终结果.如果是FullScan,反而不如普通行式存储

参考博客 http://www.hainiubl.com/topics/26