ORC(Optimized Row Columnar)file format

Optimized Row Columnar:已经过优化的 行 列 存储

ctas hive 和先建表 hive建表orc_数据

如上图所示,左图是一个hive表,有行有列,右图是用来存储数据的orc文件,那么hive表数据是如何在orc文件存储?

先将hive表横向切分,再对切分后的部分行统一进行列式存储,另一部分行再统一进行列式存储。

  • ORC文件的一个概念:stripe,直译为条、条带,若干行数据就对应着orc文件的1个stripe,

第1列数据会存储在stripe中相邻的位置,第2、3列数据也是依次存储在stripe中相邻的位置,那么前半张表就已经按照所谓的列式存储存在了文件当中,

orc文件除了按照列存储数据之外,还做了其它的优化,还存储了其它非常有用的信息,比如说:stripe开头有index data,

索引数据存了:

  1. 每一列的最大值、最小值、求和统计信息,我们来看一个实际的索引数据:

(使用hive --orcfiledump <HDFS文件路径>命令可查看ORC文件信息)


Stripe Statistics:
Stripe 1:
Column 0: count: 254 hasNull: false
Column 1: count: 254 hasNull: false min: 20220510 max: 20220510 sum: 5136009540
Column 2: count: 254 hasNull: false min: changan_park max: changan_park sum: 3048


  1. 每一列的行索引位置,例如:

Stream: column 1 section DATA start: 639 length 10 Stream: column 2 section DATA start: 649 length 7 --第一列的数据起于行偏移量639,长度10 --第二列的数据起于行偏移量649,长度7


索引数据有什么用呢?例如,要检索a<=10的数据,而stripe0的索引数据里显示a列的最小值为15,那么就会直接略过这个stripe0,这样提高查询效率,能省去大量的I/O操作。

stripe的尾部还保存着一些的信息,术语叫:stripe footer,footer底部的意思,即在stripe的底部保存着各列的编码信息,例如:


Encoding column 0: DIRECT
Encoding column 1: DIRECT_V2
Encoding column 2: DICTIONARY_V2[1]


编完码可以降低对存储空间的占用,编码是有不同的编码格式的,所以需要记录下来,咱们这字段是用什么格式去编码的,将来在读文件的时候,需要先读其编码格式,然后才能相应地解码。

每一个stripe对应着表的若干行。每一个orc文件,视表的数据量大小,是可能会有多个stripe的。

orc文件除了有stripe,还有会其它的信息,

  • 在整个orc文件的最开始,会有orc三个字,用来标识文件类型,这个可以称为文件的header文件头)。
INFO - 23/02/28 18:43:41 INFO orc.ReaderImpl: Reading ORC rows from <HDFS文件路径> with {include: null, offset: 0, length: 9223372036854775807}


  • File Footer 包含了:

Header的长度

各stripe信息:stripe的起始位置、索引的长度、数据的长度、Stripe Footer的长度等

各column的统计信息:最大值、最小值hashNull等信息

  • Postscript 包含了:

File Footer的长度

文件的压缩参数

文件的版本等信息

  • Postscript的长度(文件的最后一个字节)

orc文件结构的设计是环环相扣的,举例,若要读取a列,其大致流程为:

从最后一个字节开始读,最后一个字节保存的是Postsript的长度(L1),就可以从倒数第2个字节往前推L1,去拿到完整的PostScript的信息,postsript有file footer的长度,就可以往前推,拿到File Footer的数据,进而拿到每一个stripe的起始位置,就能定位到stripe0,stripe1,先拿stripe的index data,还得读stripe footer的编码信息,按索引信息就可以拿到对应的列,并解码