一、定义

  ORC File,它的全名是Optimized Row Columnar (ORC) file,其实就是对RCFile做了一些优化。据官方文档介绍,这种文件格式可以提供一种高效的方法来存储Hive数据。它的设计目标是来克服Hive其他格式的缺陷。运用ORC File可以提高Hive的读、写以及处理数据的性能。
和RCFile格式相比,ORC File格式有以下优点:
  (1)、每个task只输出单个文件,这样可以减少NameNode的负载;
  (2)、支持各种复杂的数据类型,比如: datetime, decimal, 以及一些复杂类型(struct, list, map, and union);
  (3)、在文件中存储了一些轻量级的索引数据;
  (4)、基于数据类型的块模式压缩:a、integer类型的列用行程长度编码(run-length encoding);b、String类型的列用字典编码(dictionary encoding);
  (5)、用多个互相独立的RecordReaders并行读相同的文件;
  (6)、无需扫描markers就可以分割文件;
  (7)、绑定读写所需要的内存;
  (8)、metadata的存储是用 Protocol Buffers的,所以它支持添加和删除一些列。

二、ORC File文件结构

  ORC File包含一组组的行数据,称为stripes,除此之外,ORC File的file footer还包含一些额外的辅助信息。在ORC File文件的最后,有一个被称为postscript的区,它主要是用来存储压缩参数及压缩页脚的大小。
在默认情况下,一个stripe的大小为250MB。大尺寸的stripes使得从HDFS读数据更高效。

  在file footer里面包含了该ORC File文件中stripes的信息,每个stripe中有多少行,以及每列的数据类型。当然,它里面还包含了列级别的一些聚合的结果,比如:count, min, max, and sum。


三、Stripe结构

  从上图我们可以看出,每个Stripe都包含index data、row data以及stripe footer。Stripe footer包含流位置的目录;Row data在表扫描的时候会用到。
  Index data包含每列的最大和最小值以及每列所在的行。行索引里面提供了偏移量,它可以跳到正确的压缩块位置。具有相对频繁的行索引,使得在stripe中快速读取的过程中可以跳过很多行,尽管这个stripe的大小很大。在默认情况下,最大可以跳过10000行。拥有通过过滤谓词而跳过大量的行的能力,你可以在表的 secondary keys 进行排序,从而可以大幅减少执行时间。比如你的表的主分区是交易日期,那么你可以对次分区(state、zip code以及last name)进行排序。

四、Hive里面如何用ORCFile

  在建Hive表的时候我们就应该指定文件的存储格式。所以你可以在Hive QL语句里面指定用ORCFile这种文件格式,如下:

CREATE TABLE ... STORED AS ORC
 
ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT ORC
 
SET hive.default.fileformat=Orc



所有关于ORCFile的参数都是在Hive QL语句的TBLPROPERTIES字段里面出现,他们是:

Key

Default

Notes

orc.compress

ZLIB

high level compression (one of NONE, ZLIB, SNAPPY)

orc.compress.size

262,144

number of bytes in each compression chunk

orc.stripe.size

268435456

number of bytes in each stripe

orc.row.index.stride

10,000

number of rows between index entries (must be >= 1000)

orc.create.index

true

whether to create row indexes

下面的例子是建立一个没有启用压缩的ORCFile的表

create table Addresses (
  name string,
  street string,
  city string,
  state string,
  zip int
) stored as orc tblproperties ("orc.compress"="NONE");
五、序列化和压缩

  对ORCFile文件中的列进行压缩是基于这列的数据类型是integer或者string。

整数列序列化

整数列序列化有两个工作流。
1,目前比特流:是值非空?
2,数据流:整数流
整型数据的序列在需要数字的共同配送的优势的方式:
1,整数是使用可变宽度编码具有用于小整数更少字节编码。
2,重复值是运行长度编码。
3,如果该值通过一个恒定的范围内(-128-127)的不同是运行长度编码。
可变宽度编码是基于谷歌的协议缓冲区,并使用高比特来表示这个字节是否是不是最后的和低7位对数据进行编码。编码负数,Z字形编码被使用,如图2所示,分别其中0 -1 1 -2和2映射成0 1 3 4和5。


每一组数字编码是这样的:
1,如果第一个字节(B0)为负:
-B0可变长度整数跟进。
2,如果第一个字节(B0)是正的:
它代表B0 + 3的整数反复
第二个字节(-128到+127)在每次重复之间增加
1可变长度整数。


在运行长度编码,第一个字节指定运行长度和值是否文本或复制。重复可以通过-128到+128。运行长度编码使用protobuf的风格变长整数。


字符串列序列化
字符串列的序列化使用的字典,形成有序且唯一列值的字典,可以加快过滤速度,提高压缩比。

字符串列序列化有两个工作流。
1,目前比特流:是值非空?
2,数据字典:对于字符串中的字节
3,字典长度:每个条目的长度
4,行数据:行值
两个字典长度和行值运行整数长度编码流。