Hive 在处理数据时,一般都需要经历文件读取和文件写出的过程,如果按照原文件的大小进行读写和传输,不仅效率查而且带宽的占用也很高,此时就需要我们这里所讲的 存储格式
和 压缩算法
不同的存储格式+压缩算法性能比较
文件存储格式不同对应不同的压缩算法,从而带来不同的性能,我们根据实际使用考虑压缩算法的性能,主要通过以下 3 个指标:
① 压缩比
压缩比越高,压缩后文件越小,所以压缩比越高越好;
压缩比越高,存储磁盘空间占用越小,可以降低单节点的磁盘IO,同时可以减少占用的带宽;
② 压缩时间
越快越好,加快数据在Hadoop集群流动的速度和磁盘 IO
的速度
③ 压缩后的文件是否可以再分割
可以分割的格式允许单一文件由多个Mapper程序处理,可以更好的并行化
压缩方式 | 压缩比 | 压缩速度 | 解压缩速度 | 是否可分割 |
---|---|---|---|---|
gzip | 13.4% | 21 MB/s | 118 MB/s | 否 |
bzip2 | 13.2% | 2.4MB/s | 9.5MB/s | 是 |
lzo | 20.5% | 135 MB/s | 410 MB/s | 是 |
snappy | 22.2% | 172 MB/s | 409 MB/s | 否 |
HIVE 中常用的存储格式对比
存储格式 | 是否默认 | 存储方式 | 压缩算法 |
---|---|---|---|
TextFile | 是 | 行式存储 | Gzip、Bzip2 |
SequenceFile | 否 | 行式存储 | NONE、RECORD、BLOCK |
Parquet | 否 | 列式存储 | Uncompress(默认)、Snappy、Gzip、Lzo |
RCFile | 否 | 数据按行分块,每块按列存储 | - |
ORCFile(RCFile的进化版本) | 否 | 数据按行分块,每块按照列存储 | NONE、ZLIB(默认)、SNAPPY |
存储方式 | 行查询效率 | 列查询效率 | 压缩效率 |
---|---|---|---|
行式存储 | 高 | 低 | 低 |
列式存储 | 低 | 高 | 高 |
TEXTFILE
HIVE 中默认的存储格式;
一般使用在数据贴源层(ODS 或 STG) ,针对需要使用脚本 LOAD 加载数据到 HIVE 数仓表中的情况;
数据存储时不压缩,因此磁盘的开销和数据解析开销比较大;
TEXTFILE 可以结合 Gzip、Bzip2 等压缩算法使用(系统自动检查,执行查询时自动解压),但使用这种方式,HIVE 不会对数据进行切分,从而无法对数据进行并行操作;
在反序列化过程中,必须逐个字符判断是不是分隔符和行结束符,因此反序列化开销会比 SequenceFile
高几十倍;
可以直接通过 LOAD
的方式从文件中加载数据到 HIVE
表中;
--- 可以不指定存储格式,默认使用 TEXTFILE
CREATE TABLE CUST_INFO
(
user_id string COMMENT '用户唯一标识'
,user_name string COMMENT '用户姓名'
)
COMMENT '用户信息明细表'
STORED AS TEXTFILE
PARTITIONED BY(ds string COMMENT '按交易日分区')
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
;
当用户的数据文件格式不能被当前 HIVE
所识别的时候,可以自定义文件格式
通过实现 inputformat
和 outputformat
来自定义输入输出格式
CREATE TABLE CUST_INFO
(
user_id string COMMENT '用户唯一标识'
,user_name string COMMENT '用户姓名'
)
COMMENT '用户信息明细表'
STORED AS
INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat'
PARTITIONED BY(ds string COMMENT '按交易日分区')
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
;
SEQUENCE FILE
HADOOP API 提供的一种二进制文件,以 key-value
的形式序列化到文件中;
支持切片;
数据加载导入方式可以通过INSERT方式加载数据;
--- 可以不指定存储格式,默认使用 TEXTFILE
CREATE TABLE CUST_INFO
(
user_id string COMMENT '用户唯一标识'
,user_name string COMMENT '用户姓名'
)
COMMENT '用户信息明细表'
STORED AS SEQUENCEFILE
PARTITIONED BY(ds string COMMENT '按交易日分区')
;
CREATE TABLE CUST_INFO
(
user_id string COMMENT '用户唯一标识'
,user_name string COMMENT '用户姓名'
)
COMMENT '用户信息明细表'
STORED AS
STORED AS
INPUTFORMAT 'org.apache.hadoop.mapred.SequenceFileInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.mapred.SequenceFileOutputFormat'
PARQUET
面向列的二进制文件格式,所以是不可以直接读取的;
文件中包括该文件的数据和元数据,因此 Parquet
格式文件是自解析的;
使用场景在 Impala
和 Hive
共享数据和元数据的场景;
CREATE TABLE CUST_INFO
(
user_id string COMMENT '用户唯一标识'
,user_name string COMMENT '用户姓名'
)
COMMENT '用户信息明细表'
STORED AS PARQUET
-- 也可以使用
-- STORED AS PARQUETFILE
PARTITIONED BY(ds string COMMENT '按交易日分区')
;
CREATE TABLE CUST_INFO
(
user_id string COMMENT '用户唯一标识'
,user_name string COMMENT '用户姓名'
)
COMMENT '用户信息明细表'
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe'
STORED AS
INPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
ORCFILE
运用 ORC
可以提高 HIVE
的读、写、计算的性能,主要使用在 DWD、DWB、DWS
层
数据按行分块,每块按照列存储;
压缩快、快速列存取;
效率比 rcfile
高,是 rcfile
的改良版本;
不考虑 ORC
的场景:需要通过 LOAD
方式加载数据到表里;需要把表里数据导出或直接可以查看等场景,这两种场景更适合使用 TEXTFILE
,易读性要比 ORC
高很多;
ORC 文件格式可以使用 HIVE 自带的命令 concatenate
快速合并小文件
CREATE TABLE CUST_INFO
(
user_id string COMMENT '用户唯一标识'
,user_name string COMMENT '用户姓名'
)
COMMENT '用户信息明细表'
-- 也可以使用 STORED AS ORCFILE
-- 指定压缩算法
STORED AS ORC TBLPROPERTIES ("orc.compress"="SNAPPY");
PARTITIONED BY(ds string COMMENT '按交易日分区')
;
CREATE TABLE CUST_INFO
(
user_id string COMMENT '用户唯一标识'
,user_name string COMMENT '用户姓名'
)
COMMENT '用户信息明细表'
ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde'
STORED AS
INPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat'
PARTITIONED BY(ds string COMMENT '按交易日分区')
;
使用总结
# 压缩比比较
ORC > PARQUET > TEXTFILE
# 查询速度
ORC > TEXTFILE > PARQUET
# 存储格式为ORC,不同的压缩算法比较压缩后的文件大小
ZLIB < SNAPPY < 非压缩
① 数据量较大
如果单个文件比较大,可以使用 Parquet
存储,lzo
压缩,可以避免由于读取不可分割大文件引发的数据倾斜
② 计算逻辑比较少
使用 ORC
存储 + ZLIB
压缩,可以尽量减少占用存储空间
③ 计算逻辑比较多
使用 ORC
存储 + SNAPPY
压缩,可以提高读写速度,从而提高整体计算性能