Hive存储格式对比

Apache Hive支持Apache Hadoop中使用的几种熟悉的文件格式,如TextFile,RCFile,SequenceFile,AVRO,ORC和Parquet格式。Cloudera Impala也支持这些文件格式。 在建表时使用STORED AS (TextFile|RCFile|SequenceFile|AVRO|ORC|Parquet)来指定存储格式

TextFile每一行都是一条记录,每行都以换行符(\ n)结尾。数据不做压缩,磁盘开销大,数据解析开销大。可结合Gzip、Bzip2使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。

SequenceFile是Hadoop API提供的一种二进制文件支持,其具有使用方便、可分割、可压缩的特点。支持三种压缩选择:NONE, RECORD, BLOCK。 Record压缩率低,一般建议使用BLOCK压缩。

RCFile是一种行列存储相结合的存储方式。首先,其将数据按行分块,保证同一个record在一个块上,避免读一个记录需要读取多个block。其次,块数据列式存储,有利于数据压缩和快速的列存取。

AVRO是开源项目,为Hadoop提供数据序列化和数据交换服务。您可以在Hadoop生态系统和以任何编程语言编写的程序之间交换数据。Avro是基于大数据Hadoop的应用程序中流行的文件格式之一。

ORC文件代表了优化排柱状的文件格式。ORC文件格式提供了一种将数据存储在Hive表中的高效方法。这个文件系统实际上是为了克服其他Hive文件格式的限制而设计的。Hive从大型表读取,写入和处理数据时,使用ORC文件可以提高性能。

Parquet是一个面向列的二进制文件格式。Parquet对于大型查询的类型是高效的。对于扫描特定表格中的特定列的查询,Parquet特别有用。Parquet桌子使用压缩Snappy,gzip;目前Snappy默认。

1 概述
官方链接:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-StorageFormatsStorageFormatsRowFormat,StorageFormat,andSerDe
上一篇博客我们详细的介绍了压缩的使用,本文将详细介绍Hive中的存储格式,下面列出官方给出的存储格式:

[STORED AS file_format]
file_format:
  : SEQUENCEFILE
  | TEXTFILE    -- (Default, depending on hive.default.fileformat configuration)
  | RCFILE      -- (Note: Available in Hive 0.6.0 and later)
  | ORC         -- (Note: Available in Hive 0.11.0 and later)
  | PARQUET     -- (Note: Available in Hive 0.13.0 and later)
  | AVRO        -- (Note: Available in Hive 0.14.0 and later)
  | INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname

TEXTFILE是默认的存储格式,下面进行详细的介绍几种常用的存储格式。

2 TEXTFILE:文本文件

  1. 存储方式:行存储;
  2. 默认格式,数据不做压缩,磁盘开销大,数据解析开销大。可结合Gzip、Bzip2使用(系统自动检查,执行查询时自动解压),但使用这种方式,hive不会对数据进行切分,从而无法对数据进行并行操作。

创建一张tt表进行分析

CREATE TABLE tt (
id int,
name string
) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t";

查看tt表格信息

desc formatted tt
# Storage Information            
SerDe Library:          org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe       
InputFormat:            org.apache.hadoop.mapred.TextInputFormat         
OutputFormat:           org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat       
Compressed:             No                       
Num Buckets:            -1                       
Bucket Columns:         []                       
Sort Columns:           []                       
Storage Desc Params:             
        field.delim             \t                  
        serialization.format    \t 


这两种方式也是创建TEXTFILE的存储格式:

方式一:
CREATE TABLE tt2 (
id int,
name string
) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS TEXTFILE;
方式二:
CREATE TABLE tt3 (
id int,
name string
) ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS 
INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';


3 Sequencefile:二进制文件

Record:存储SequenceFile通用的KV数据格式,Key和Value都是二进制变长的数据。Record表示Key和Value的byte的总和。
Sync:主要是用来扫描和恢复数据的,以至于读取数据的Reader不会迷失。
Header:存储了如下信息:文件标识符SEQ,key和value的格式说明,以及压缩的相关信息,metadata等信息。
metadata:包含文件头所需要的数据:文件标识、Sync标识、数据格式说明(含压缩)、文件元数据(时间、owner、权限等)、检验信息等。

存储方式:行存储;

  1. SequenceFile是Hadoop API 提供的一种二进制文件,它将数据(key,value)的形式序列化到文件里。这样的二进制文件内部使用Hadoop 的标准的Writable 接口实现序列化和反序列化。它与Hadoop API中的MapFile 是互相兼容的。
  2. Hive 中的SequenceFile 继承自Hadoop API 的SequenceFile,只是它的key为空。使用value 存放实际的值。 这样是为了避免MR 在执行map 阶段的排序过程。
  3. SEQUENCEFILE比TextFile 多了一些冗余信息,所以要大一些。

创建page_views_seq表

create table page_views_seq(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS SEQUENCEFILE;

这时候并不能使用load将数据加载到存储格式为SEQUENCEFILE的表中,需要先创建TextFile的存储格式的表中,然后insert into到存储格式为SEQUENCEFILE的表中。

插入数据:insert into table page_views_seq select * from page_views; 
数据大小对比:
TextFile存储格式的大小
[hadoop@hadoop ~]$ hdfs dfs -du -s -h /user/hive/warehouse/hive.db/page_views
18.1 M   /user/hive/warehouse/hive.db/page_views
SEQUENCEFILE存储格式的大小
[hadoop@hadoop ~]$ hdfs dfs -du -s -h /user/hive/warehouse/hive.db/page_views_seq 
19.6 M   /user/hive/warehouse/hive.db/page_views_seq
原始大小
[hadoop@hadoop ~]$ du -sh data/page_views.dat
19M     data/page_views.dat



4 Rcfile

1. 这个架构是利用了先行式存储再列式存储的方式。在每个row group中为列式存储,相对于sequenceFile的大小,有一定优势,大概比textFile小10%。
2. 当查询过程中,针对它并不关心的列时,它会在IO上跳过这些列。须要说明的是。RCFile在map阶段从远端拷贝仍然是拷贝整个数据块,而且复制到本地文件夹后,RCFile并非真正直接跳过不须要的列,并跳到须要读取的列, 而是通过扫描每个row group的头部定义来实现的。
可是在整个HDFS Block 级别的头部并未定义每个列从哪个row group起始到哪个row group结束。所以在读取全部列的情况下。RCFile的性能反而没有SequenceFile高。

创建page_views_seq表

create table page_views_rcfile(
track_time string,
url string,
session_id string,
referer string,
ip string,
end_user_id string,
city_id string
)ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS RCFILE;
插入数据:
insert into table page_views_rcfile select * from page_views;
查看大小:
hdfs dfs -du -s -h /user/hive/warehouse/hive.db/page_views_rcfile
17.9 M  /user/hive/warehouse/hive.db/page_views_rcfile


5 ORC
官方网站
ORC的全称是(Optimized Row Columnar),ORC文件格式是一种Hadoop生态圈中的列式存储格式,它的产生早在2013年初,最初产生自Apache Hive,用于降低Hadoop数据存储空间和加速Hive查询速度。和Parquet类似,它并不是一个单纯的列式存储格式,仍然是首先根据行组分割整个表,在每一个行组内进行按列存储。ORC文件是自描述的,它的元数据使用Protocol Buffers序列化,并且文件中的数据尽可能的压缩以降低存储空间的消耗,目前也被Spark SQL、Presto等查询引擎支持,但是Impala对于ORC目前没有支持,仍然使用Parquet作为主要的列式存储格式。2015年ORC项目被Apache项目基金会提升为Apache顶级项目。ORC具有以下一些优势:
1. ORC是列式存储,有多种文件压缩方式,并且有着很高的压缩比。
2. 文件是可切分(Split)的。因此,在Hive中使用ORC作为表的文件存储格式,不仅节省HDFS存储资源,查询任务的输入数据量减少,使用的MapTask也就减少了。
3. 提供了多种索引,row group index、bloom filter index。
4. ORC可以支持复杂的数据结构(比如Map等)

和Parquet类似,ORC文件也是以二进制方式存储的,所以是不可以直接读取,ORC文件也是自解析的,它包含许多的元数据,这些元数据都是同构ProtoBuffer进行序列化的。ORC的文件结构如下图:


ORC文件:保存在文件系统上的普通二进制文件,一个ORC文件中可以包含多个stripe,每一个stripe包含多条记录,这些记录按照列进行独立存储,对应到Parquet中的row group的概念。
文件级元数据:包括文件的描述信息PostScript、文件meta信息(包括整个文件的统计信息)、所有stripe的信息和文件schema信息。
stripe:一组行形成一个stripe,每次读取文件是以行组为单位的,一般为HDFS的块大小,保存了每一列的索引和数据。
stripe元数据:保存stripe的位置、每一个列的在该stripe的统计信息以及所有的stream类型和位置。
row group:索引的最小单位,一个stripe中包含多个row group,默认为10000个值组成。
stream:一个stream表示文件中一段有效的数据,包括索引和数据两类。索引stream保存每一个row group的位置和统计信息,数据stream包括多种类型的数据,具体需要哪几种是由该列类型和编码方式决定。

  1. 读取ORC文件是从尾部开始的,第一次读取16KB的大小,尽可能的将Postscript和Footer数据都读入内存。文件的最后一个字节保存着PostScript的长度,它的长度不会超过256字节,PostScript中保存着整个文件的元数据信息,它包括文件的压缩格式、文件内部每一个压缩块的最大长度(每次分配内存的大小)、Footer长度,以及一些版本信息。在Postscript和Footer之间存储着整个文件的统计信息(上图中未画出),这部分的统计信息包括每一个stripe中每一列的信息,主要统计成员数、最大值、最小值、是否有空值等。
  2. 接下来读取文件的Footer信息,它包含了每一个stripe的长度和偏移量,该文件的schema信息(将schema树按照schema中的编号保存在数组中)、整个文件的统计信息以及每一个row group的行数。
  3. 处理stripe时首先从Footer中获取每一个stripe的其实位置和长度、每一个stripe的Footer数据(元数据,记录了index和data的的长度),整个striper被分为index和data两部分,stripe内部是按照row group进行分块的(每一个row group中多少条记录在文件的Footer中存储),row group内部按列存储。每一个row group由多个stream保存数据和索引信息。每一个stream的数据会根据该列的类型使用特定的压缩算法保存。

在建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字段里面出现,他们是:


总结: ORC能很大程序的节省存储和计算资源,但它在读写时候需要消耗额外的CPU资源来压缩和解压缩,当然这部分的CPU消耗是非常少的。
对性能提升的另一个方面是通过在ORC文件中为每一个字段建立一个轻量级的索引,来判定一个文件中是否满足WHERE子句中的过滤条件。比如:当执行HQL语句”SELECT COUNT(1) FROM lxw1234_orc WHERE id = 0”时候,先从ORC文件的metadata中读取索引信息,快速定位到id=0所在的offsets,如果从索引信息中没有发现id=0的信息,则直接跳过该文件。

 

存储格式对比
存储格式存储方式特点
TextFile行存储存储空间消耗比较大,并且压缩的text 无法分割和合并 查询的效率最低,可以直接存储,加载数据的速度最高
SequenceFile行存储存储空间消耗最大,压缩的文件可以分割和合并 查询效率高,需要通过text文件转化来加载
RCFile数据按行分块 每块按照列存储

存储空间最小,

查询的效率最高 ,

需要通过text文件转化来加载,

加载的速度最低。

压缩快 快速列存取。

读记录尽量涉及到的block最少 

读取需要的列只需要读取每个row group 的头部定义。 

读取全量数据的操作 性能可能比sequencefile没有明显的优势

ORCFile数据按行分块 每块按照列存储压缩快,快速列存取 ,效率比rcfile高,是rcfile的改良版本
Parquet列存储相对于PRC,Parquet压缩比较低,查询效率较低,不支持update、insert和ACID.但是Parquet支持Impala查询引擎

 

Parquet与ORC对比
 

Parquet

http://parquet.apache.org

Orc

http://orc.apache.org

发展状态目前都是Apache开源的顶级项目,列式存储引擎目前都是Apache开源的顶级项目,列式存储引擎
开发语言JavaJava
主导公司Twitter/ClouderaHortonworks

 ACID

不支持支持ACID事务
修改操作(update,delete)不支持支持

支持索引(统计信息)

粗粒度索引

block/group/chunk级别统计信息

粗粒度索引

file/stripe/row级别统计信息,

不能精确到列建立索引

支持的查询引擎Apache Drill、ImpalaApache Hive
查询性能Orc性能更高一点Orc性能更高一点
压缩比Orc压缩比更高(见下图)Orc压缩比更高(见下图)
列编码支持多种编码,字典,RLE,Delta等支持主流编码,与Parquet类似

 

总结:如果仅仅是在HIve中存储和查询,建议使用ORC格式,如果在Hive中存储,而使用Impala查询,建议使用Parquet。

参考资料:

https://www.waitig.com/hive%E7%AC%94%E8%AE%B0%E6%95%B4%E7%90%86%E4%B9%8B-%E6%96%87%E4%BB%B6%E5%AD%98%E5%82%A8%E6%A0%BC%E5%BC%8F.html

http://46aae4d1e2371e4aa769798941cef698.devproxy.yunshipei.com/jiangshouzhuang/article/details/51416744

http://46aae4d1e2371e4aa769798941cef698.devproxy.yunshipei.com/jiangshouzhuang/article/details/51416744

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值