Hive存储格式行存储和列存储
如图,左面是行存储,Hive的数据存储在Hadoop之上,但是hadoop存储的时候是以块进行存储的。行式存储就一行不管你是多少列,都是在一个bock里面的。比如你一行数据有各种类型,比如int、string等等。如果进行压缩的这种方式的压缩比,是肯定大于同一种类型的方式的压缩,不同的数据类型混在一起。
在我们日常工作中,我司里的表,少说几百个字段。规模在大一些的公司,上千个字段应该不是问题。如果是行式存储,行式存储的特点一行记录所有的字段,也就是说这一行的数据全部在一起。如果我在一张有1000个字段的表里,取某俩个字段。那么行存储会读取1000列,在把我要查询的列拿出来,这样性能肯定下降的。## Hive文件存储格式
右边是列式存储,RowID是一列,Time又是一列存储在一起。每一列的数据结构是相同的,他的压缩比肯定是优于行式存储的。其次就是查询的问题,在1000个字段里面我取其中俩个不用全部读出来字段。只要读取对应的列就行了,因为他们是一个列在一起的。其实列存储也不是万能的,比如我select * 查询全部字段。这种肯定就不如行存储了。但是大数据场景一般使用列存储
- Hive在创建表的时候可以使用STORED AS创建,如下官网示例
[STORED AS file_format]-- (这里指定你要创建的格式是什么)
| STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]
]
--示例
file_format:
: SEQUENCEFILE
| TEXTFILE -- (Default, 这是hive默认的格式)
| 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)
| JSONFILE -- (Note: Available in Hive 4.0.0 and later)
--input_format_classname 是可以使用自定义的类,output_format_classname 也是同理
--比如create table student(id int,name, string ,age int)STORED AS INPUTFORMAT 'org.apache.hadoop.mappred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.mappred.TextInputFormat'
| INPUTFORMAT input_format_classname OUTPUTFORMAT output_format_classname
1)、SEQUENCEFILE: Hadoop API提供的一种二进制文件支持,其具有使用方便、可分割、可压缩的特点。
2)、TEXTFILE: textfile为默认格式,存储方式为行存储。数据不做压缩,磁盘开销大,数据解析开销大。
3)、RCFILE(Record Columnar File): 一种行列存储相结合的存储方式。
4)、ORC: 数据按照行分块,每个块按照列存储,其中每个块都存储有一个索引。hive给出的新格式,属于RCFILE的升级版,性能有大幅度提升,而且数据可以压缩存储,压缩快 快速列存取。
ORC这种文件格式可以作用于表或者表的分区,可以通过以下几种方式进行指定:
CREATE TABLE ... STORED AS ORC (常用)
ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT ORC
SET hive.default.fileformat=ORC
5)、PARQUET: Parquet也是一种行式存储,同时具有很好的压缩性能;同时可以减少大量的表扫描和反序列化的时间。
如果Hive要使用存储格式,则必须先存在一张相同数据的存储格式为TEXTFILE的表table_t0,然后在建表时使用“insert into table table_stored_file_ORC select from table_t0;”创建。或者使用”create table as select from table_t0;”创建。
下面是对TextFile、SequenceFile、RcFile、ORC、Parquet存储的比较
存储格式
1、 TEXTFILE
Hive中的默认的存储格式纯文本,默认不压缩的。也可自定义压缩,下面有一个18M的文件,我们用它来测试
[ruoze@ruozedata001 ~]$ hdfs dfs -du -s -h /compress/page_views.dat
18.1 M 18.1 M /compress/page_views.dat
创建一张hive表
create table `page_views`(
`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 TEXTFILE(默认就是,可以不用加);
--加载数据
load data inpath '/compress/page_views.dat' into table `page_views`;
查询表大小
[ruoze@ruozedata001 ~]$ hdfs dfs -du -s -h /user/hive/warehouse/page_views
18.1 M 18.1 M /user/hive/warehouse/page_views/page_views.dat
查询时读取数据量大小(单位字节,以下用同一个SQL测试)
select count(1) from page_views where session_id="B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1";
-------------------------------------------------------
HDFS Read: 19024015
2、SequenceFile
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;
#查询导入
insert into table page_views_seq select * from page_views;
查询表大小
[ruoze@ruozedata001 ~]$ hdfs dfs -du -s -h /user/hive/warehouse/page_views_seq
19.6 M 19.6 M /user/hive/warehouse/page_views_seq
数据变大,生产上不建议使用
查询时读取数据量大小(字节)
HDFS Read: 20510541
3、RCFile
create table page_views_rcfile
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS RCFile
as select * from page_views
查询表大小
[ruoze@ruozedata001 ~]$ hdfs dfs -du -s -h /user/hive/warehouse/page_views_rcfile
17.9 M 17.9 M /user/hive/warehouse/page_views_rcfile
查询读取数据量大小
select count(1) from page_views_rcfile where session_id="B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1";
------------------------------------------------------------
HDFS Read: 3726731
4、ORC
create table page_views_orc
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS ORC
as select * from page_views
查询表大小
[ruoze@ruozedata001 ~]$ hdfs dfs -du -s -h /user/hive/warehouse/page_views_orc
2.8 M 2.8 M /user/hive/warehouse/page_views_orc
查询读取数据量大小
select count(1) from page_views_orc where session_id="B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1";
-----------------------------------------------
HDFS Read: 1258821
5、Parquet
create table page_views_par
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS Parquet
as select * from page_views;
查询表大小
[ruoze@ruozedata001 ~]$ hdfs dfs -du -s -h /user/hive/warehouse/page_views_par
13.1 M 13.1 M /user/hive/warehouse/page_views_par
查询读取数据量大小
select count(1) from page_views_par where session_id="B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1";
--------------------------------------------------
HDFS Read: 2688334
使用压缩方式
1、Bzip2
set hive.exec.compress.output=true;
set mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.BZip2Codec;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.BZip2Codec;
create table page_views_bizp2 row format delimited fields terminated by '\t' as select * from page_views;
查询表大小
[ruoze@ruozedata001 ~]$ hdfs dfs -du -h /user/hive/warehouse/page_views_bizp2
3.6 M 3.6 M /user/hive/warehouse/page_views_bizp2/000000_0.bz2
查询读取数据量大小
select count(1) from page_views_bzip2 where session_id="B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1";
-------------------------------------------------
HDFS Read: 4075669
2、ORC+Zlip结合
create table page_views_orc_zlib
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS ORC
TBLPROPERTIES("orc.compress"="ZLIB")
as select * from page_views;
查询表大小
[ruoze@ruozedata001 ~]$ hdfs dfs -du -s -h /user/hive/warehouse/page_views_orc_zlib
2.8 M 2.8 M /user/hive/warehouse/page_views_orc_zlib
查询读取数据量大小
压缩只有ZLIB和SNAPPY,官网地址orc
select count(1) from page_views_orc_zlib where session_id="B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1";
-------------------------------------------------------
HDFS Read: 1258883
3、Parquet+gzip结合
set parquet.compression=gzip;
create table page_views_parquet_gzip
ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS PARQUET
as select * from page_views;
查询表大小
[ruoze@ruozedata001 ~]$ hdfs dfs -du -s -h /user/hive/warehouse/page_views_parquet_gzip
3.9 M 3.9 M /user/hive/warehouse/page_views_parquet_gzip
查询读取数据量大小
select count(1) from page_views_parquet_gzip where session_id="B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1";
--------------------------------------------------
HDFS Read: 1625835
4、Parquet+Lzo结合
SET hive.exec.compress.output=true;
SET mapreduce.output.fileoutputformat.compress.codec=com.hadoop.compression.lzo.lzopCodec;
SET mapred.output.compression.codec=com.hadoop.compression.lzo.LzopCodec;
create table page_views_parquet_lzo ROW FORMAT DELIMITED FIELDS TERMINATED BY "\t"
STORED AS PARQUET
TBLPROPERTIES("parquet.compression"="lzo")
as select * from page_views;
查询表大小
[ruoze@ruozedata001 ~]$ hdfs dfs -du -s -h /user/hive/warehouse/page_views_parquet_lzo
6.2 M 6.2 M /user/hive/warehouse/page_views_parquet_lzo
查询读取数据量大小
select count(1) from page_views_parquet_lzo where session_id="B58W48U4WKZCJ5D1T3Z9ZY88RU7QA7B1";
--------------------------------------------------
HDFS Read: 2434096