Hive存储格式之ORC File详解,什么是ORC File

概述

本文基于上一篇文章 Hive存储格式之RCFile详解,RCFile的过去现在未来 撰写,读过上一篇文章,则更好理解以下内容。

2013年,HortonWorks在RCFile的基础上开发出了ORC File(Optimied Row Columnar),在2015年成为Apache的顶级项目。以下简称ORC。

RCFile在被Facebook开源后,作为Hive之中典型的列存储模型被广泛使用,相比于之前的存储格式有很大的优势,但是同样RCFile仍然有值得改进的地方。

ORC 做了相关优化,在Hive的使用中有更好的表现,它支持复杂数据类型、ACID支持及内置索引支持,非常适合海量数据的存储。

ORC并不是一个单纯的列式存储格式,它也遵循了先水平分区,再垂直分区的理念,采用混合存储结构。

除了Hive,目前也被Spark SQL,Flink,Presto,Impala等查询引擎支持。

我上一篇中提及RCFile的两个优化方向:

  • 不同数据类型的列使用不同的压缩方案(Facebook论文指出的优化方向-未做)
  • 全局检索性能查,提供更合理快速的检索功能

ORC相对于RCFile提供了更优的解决方案:

  • 列数据的类型感知:与RCFile之前未对列数据都统一为BLOB(binary large object-二进制大对象)数据不同,ORC可以感知列的数据类型,做出更为合理的数据压缩选择。
  • 嵌套数据类型支持:ORC可以在列数据之中插入Struct,Union,List,Map等数据,让数据操作更加灵活,也更加适合非结构化数据的存储与处理。
  • 谓词下推:这个算是RCFile原先功能的补强,在元数据层面增加了很多内容,来利用谓词下推加速处理的过程。ORC自己称之为轻量级索引,其实就是一些相较于RCFile更为详细的统计数据。
  • 文件可切分:文件可切分,在Hive中使用ORC作为表的文件存储格式,不仅可以节省HDFS的存储资源,查询任务的输入数据量减少,使用的MapTask也就减少了。
  • 内存管理:提供了一个memory manager来管理内存使用情况。

接下来我们通过以下几部分来完整的理解一下什么是ORC。

文件存储结构

ORC文件是以二进制的方式存储的,不可以直接读取,但由于ORC的自描述特性,其读写不依赖于 Hive Metastore 或任何其他外部元数据。本身存储了文件数据、数据类型及编码信息。因为文件是自包含的,所以读取ORC文件数据无需考虑用户使用环境。

由于ORC的元数据使用Protocol Buffers序列化,添加新字段不会破坏原有的数据结构。

如下图所示,ORC引入了三个新的组件。

  • Stripe

  • File Footer

  • PostScript

Stripe

ORC的主体由多个Stripe(也成为条带)组成,类似于RCFile中的行组,但是其远远大于行组的4MB,最大可达到250M大小,更大的Stripe使ORC的数据读取更加高效。

每个Stripe彼此独立,这个很好理解,因为每行数据彼此独立,而每行数据不会在多个Stripe中。

在Hive中每个Stripe通常由不同的任务处理。列存储格式的定义特征是每一列的数据是分开存储的,从文件中读取数据的速度应该与读取的列数成正比。

Stripe又包含三个部分:Index Data、Row Data和Stripe Footer。索引和数据部分都按列划分,因此只需要读取所需列的数据。

Index Data

索引数据部分,存储每列的统计数据。Index Data在Stripe的最前面,因为它们只在使用谓词下推或寻找指定行时加载。(这里主要利用索引功能实现的,具体见下文条带级别索引)

Row Data

实际存储数据的单元,利用列存储原理,对不同列可以实现不同的压缩方案,所有的列数据可以组成行数据。

Stripe Footer

存储了每个列的编码,数据流目录与位置。

message StripeFooter {
   
 // the location of each stream
 repeated Stream streams = 1;
 // the encoding of each column
 repeated ColumnEncoding columns = 2;
 optional string writerTimezone = 3;
 // one for each column encryption variant
 repeated StripeEncryptionVariant encryption = 4;
}
两个补充名词

在数据存储和解析的过程中还使用到了两个比较抽象的名词描述,分别为Row Group和Stream,这里单独说明一下。

Row Group

这里的Row Group和RCFile里的行组不是同一个概念,RCFile的行组对标的是ORC中的Stripe。

Row Group是虚拟的(下文有详细介绍),Row Group Index是索引(index)的最小单位,一个Index Data中包含多个行组。默认值为 10000 个值。每一个Row Group Index中有多少条记录在文件的Footer中存储。

Stream

本节以上部分是Stripe的逻辑结构,具体数据存储还有更细粒度的单位存在,那就是Stream。在ORC文件中,每一列都存储在多个Stream中,这些Stream在文件中彼此相邻存储。Stream保存了用户真正关心的业务数据内容。

这也是ORC列式存储的根本所在:正如开头的架构图一样,一个大文件由各Stripe分割,每个Stripe负责多个行组,在一个Stripe负责的这多行范围内,各列的数据内容以Stream的形式按列存储。为了描述每个Stream,ORC以字节为单位存储Stream的类型、列ID和Stream的大小。每个Stream中存储内容的详细信息取决于列的类型和编码。也就是说,在一个Stripe中的每一列都可能有多个表示不同信息的Stream,存储内容如下所示:

message Stream {
   
 enum Kind {
   
   // boolean stream of whether the next value is non-null
   PRESENT = 0;
   // the primary data stream
   DATA = 1;
   // the length
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鲁边

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值