在Hive中,文件的存储格式主要有:TEXTFILE、SEQUENCEFILE、ORC、PARQUET。
其中,TEXTFILE、SEQUENCEFILE是基于行存储,ORC、PARQUET基于列存储。
1. 行存储和列存储
上图中左边为逻辑表,右上为行存储,右下为列存储。
当查询结果为一整行的时候,行存储效率会高一些;当查询表中某几列时,列存储的效率会更高。
在对数据的压缩方面,列存储比行存储更有优势,所以列存储占用空间相对小一些。
2. TEXTFILE
TEXTFILE是Hive的默认存储格式,数据不做压缩,磁盘开销大。实际生产中很少用TEXTFILE存储。
3. ORC
ORC(Optimized Row Columnar)从Hive0.11.0开始出现,提高了Hive在写入、读取、计算数据时的性能。ORC文件默认使用ZLIB压缩。
ORC文件由stripe、file footer、postscript三部分组成:
3.1 Stripe
一个ORC文件,可以包含多个Stripe,Stripe默认大小250M。
Stripe由Index Data、Row Data、Stripe Footer三部分组成。
(1)Index Data
轻量级索引,默认每隔1w行做一个索引,目的是记录某行的各个字段在Row Data中的偏移量。
(2)Row Data
真正存储数据的部分,对每个列进行编码存储。
(3)Stripe Footer
存储stripe的元数据信息。
3.2 File Footer
每个ORC文件中存有一个file footer,里面记录了各个stripe存储的行数,每个列的数据类型等信息。
3.3 Postscript
Postscript在ORC文件的尾部,记录了整个文件的压缩类型、File Footer的长度信息等。ORC文件是从后往前读的,先读取Postscript,获取File Footer的信息,再从File Footer里读取Stripe的信息,最后定位到需要读取的数据。
Hive中可以采用如下三种方式使数据存储到ORC文件中:
(1) CREATE TABLE ... STORED AS ORC
(2) ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT ORC
(3) SET hive.default.fileformat=Orc
Hive 0.14.0版本后还可以使用CONCATENATE命令合并ORC文件:
ALTER TABLE table_name [PARTITION partition_spec] CONCATENATE
4. PARQUET
Parquet是面向分析型系统的列式存储格式,由Twitter和Cloudera合作开发,2015年5月成为Apache的顶级项目。
Parquet文件是以二进制格式存储的,所以不能直接读取。
通常情况下,Parquet文件在存储时会按照Block大小设置行组(Row Group)的大小,这样Parquet文件就可以被多个mapper处理,增加了任务的并行度。
Parquet文件格式如下图所示:
一个Parquet文件中可以存储多个行组,文件的首位都是该文件的Magic Number,用于校验它是否是一个Parquet文件。
Footer length记录了文件元数据的大小,通过该值和文件长度可以计算出元数据的偏移量,文件的元数据中包括每一个行组的元数据信息和该文件存储数据的Schema信息。
除了文件中每一个行组的元数据,每一页的开始都会存储该页的元数据,在Parquet中,有三种类型的页:数据页、字典页和索引页。
数据页:用于存储当前行组中该列的值;
字典页:存储该列值的编码字典,每一个列块中最多包含一个字典页;
索引页:用来存储当前行组下该列的索引,目前Parquet中还不支持索引页。
由于Parquet在Hive 0.10 - 0.12中以插件形式存在,Hive 0.13及以后版本才得以集成,所以建表语句有所不同。
Hive 0.10 - 0.12:
CREATE TABLE parquet_test (
id int,
str string,
mp MAP<STRING,STRING>,
lst ARRAY<STRING>,
strct STRUCT<A:STRING,B:STRING>)
PARTITIONED BY (part string)
ROW FORMAT SERDE 'parquet.hive.serde.ParquetHiveSerDe'
STORED AS
INPUTFORMAT 'parquet.hive.DeprecatedParquetInputFormat'
OUTPUTFORMAT 'parquet.hive.DeprecatedParquetOutputFormat';
Hive 0.13+:
CREATE TABLE parquet_test (
id int,
str string,
mp MAP<STRING,STRING>,
lst ARRAY<STRING>,
strct STRUCT<A:STRING,B:STRING>)
PARTITIONED BY (part string)
STORED AS PARQUET;
总结
Hive支持的文件格式主要有:行存储(TEXTFILE、SEQUENCEFILE) 和列存储(ORC、PARQUET);
在实际生产环境,使用ORC和PARQUET的情况比较多;