浅析列式存储格式Parquet和ORC | 青训营

195 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第14天。

引言

  • 大数据作业简化来说就是从存储服务取数据,由计算引擎对数据进行解析和计算,最后将结果存储或可视化展示。
  • 影响大数据计算作业性能的关键因素
    1. 如何高效从存储读取所需的数据
    2. 如何高效的计算数据
  • 数据格式层:在计算层与存储层之间,定义了存储层文件内部的组织格式,计算引擎通过格式层的支持来读写文件。
  • 数据形态
    • 存储层:File ,Blocks
    • 格式层:File内部的数据布局( Layout + Schema )
    • 计算层:Rows + Columns
  • 数据查询分析场景
    • OLTP:在线业务系统中,具有事务性,低延时,高并发等特点。
      • 数据模型特征:Schema相对简单,数据维度不多,数据规模较小,主要采用行式存储。
    • OLAP:大数据分析系统中,数据量大对吞吐性要求高,相对来说对事务延时并发等要求较小。
      • 数据模型特征:Schema复杂,数据维度很多,数据规模大,主要采用列式存储。
  • 列存的应用场景
    • 大数据分析系统:SQL-on-Hadoop,数据湖分析
    • 数据仓库:ClickHouse , Greenplum,阿里云MaxCompute

Parquet和ORC的原理和区别

Parquet简介

  • Parquet是大数据分析领域使用最广的列存格式,Spark推荐的存储格式,参照Google的Dremel列式存储模型研发的。
  • 相对于行式存储,虽然数据进行了高效压缩,但性能不降反升。
  • 数据布局 image.png
    • RowGroup:每一个行组包含一定数量或者固定大小的行的集合
    • ColumnChunk:RowGroup中按照列切分成多个ColumnChunk
    • Page:ColumnChunk内部继续切分成Page,一般建议8KB大小。压缩和编码的基本单元
      • 根据保存的数据类型分为:Data Page ,Dictionary Page , Index Page
    • Footer保存文件的元信息
      • Schema
      • Config
      • Metadata
        • RowGroup Meta
          • Column Meta
  • 编码格式种类
    • Plain直接存储原始数据
    • Run Length Encoding (RLE):适用于列基数不大,重复值较多的场景,例如: Boolean、枚举、固定的选项等。
    • Bit-Pack Encoding:配合RLE编码使用让整形数字存储的更加紧凑,可将重复0压缩。
    • 字典编码Dictionary Encoding:适用于列基数不大的场景,存储数据格式是字符串,构造字典表,写入到Dictionary Page。把数据用字典Index替换,然后用RLE编码。
    • 默认场景下parquet- mr会自动根据数据特征选择业务
    • 自定义: org.apache parquet.column.values.factory.ValuesWriterFactory
  • Page完成Encoding以后,进行压缩
    • 支持多种压缩算法:snappy、gzip、zstd。
  • 支持引入Bloom Filter加速过滤匹配判定,提前过滤掉大量不想干的数据。

ORC简介

  • 大数据分析领域使用最广的列存格式之一,出自Hive
  • 数据模型
    • ORC会给包括根节点在内的中间节点都创建一个Column
    • 嵌套类型或者集合类型支持和Parquet差别较大
  • 数据布局类似Parquet
    • Rooter + Stripe + Column + Page (Row Group)结构
    • Encoding / Compression / Index支持上和Parquet几乎一致

两者对比

  • 从原理层面,最大的差别就是对于NestedType和复杂类型处理上
  • Parquet的算法上要复杂很多,带来的CPU的开销比ORC要略大
  • ORC的算法上相对简单,但是要读取更多的数据
  • Spark生态下Parquet比较普遍,Hive生态下ORC有原生支持