Hive之存储和压缩


Hive系列


第十章 存储和压缩

10.1 首先看一下Hadoop中的压缩

10.1.1 基本概念

1、概念

压缩是一种通过特定的算法来减小计算机文件大小的机制。这种机制是一种很方便的发明,尤其是对网络用户,因为它可以减小文件的字节总数,使文件能够通过较慢的互联网连接实现更快传输,此外还可以减少文件的磁盘占用空间。

2、优缺点

压缩优点:减少磁盘IO、减少磁盘存储空间。
压缩缺点:增加CPU开销,也就是需要大量的计算能力去解压缩。

3、原则

(1)运算密集型任务(经常需要计算),少用压缩
(2)IO密集型任务(经常需要输入输出,也就是需要传输),多用压缩

10.1.2 Hadoop中的压缩编码

1、常见的压缩编码

压缩编码 Hadoop是否自带 算法 文件扩展名 是否支持切片 换压缩格式后,原程序是否需要修改
DEFLATE 是,直接使用 DEFLATE .deflate 和文本处理一样,不需要修改
Gzip 是,直接使用 DEFLATE .gz 和文本处理一样,不需要修改
bzip2 是,直接使用 bzip2 .bz2 和文本处理一样,不需要修改
LZO 否,需要安装 LZO .lzo 需要建索引,还需要指定输入格式
Snappy 是,直接使用 Snappy .snappy 和文本处理一样,不需要修改

2、部分性能对比

压缩算法 原文件大小 压缩之后文件大小 压缩速度 解压速度
gzip 8.3GB 1.8GB 17.5MB/s 58MB/s
bzip2 8.3GB 1.1GB 2.4MB/s 9.5MB/s
LZO 8.3GB 2.9GB 49.3MB/s 74.6MB/s

注: 数据来源于网络。

再来一个Snappy的。链接: http://google.github.io/snappy/

Snappy is a compression/decompression library. It does not aim for maximum compression, or compatibility with any other compression library; instead, it aims for very high speeds and reasonable compression. For instance, compared to the fastest mode of zlib, Snappy is an order of magnitude faster for most inputs, but the resulting compressed files are anywhere from 20% to 100% bigger. On a single core of a Core i7 processor in 64-bit mode, Snappy compresses at about 250 MB/sec or more and decompresses at about 500 MB/sec or more.

10.1.3 多种压缩方式优缺点及适用场景

压缩方式选择时考虑的几个方面:解、压缩速度、压缩率、压缩文件是否可以支持切片。

1、Gzip压缩
优点:压缩率较高
缺点:不支持Split切片;解、压缩 速度一般

2、Bzip2压缩
优点:压缩率高,支持Split切片 
缺点:解、压缩速度慢

3、Lzo压缩
优点:解、压缩速度比较快,支持Split切片
缺点:压缩率一般,想支持切片需要额外创建索引

4、Snappy压缩
优点:解、压缩速度快  
缺点:不支持Split切片,压缩率一般 

10.1.4 压缩的位置

1、Map前(输入端)
无须显示指定使用的解压缩编码方式。Hadoop自动检查文件扩展名,如果扩展名能够匹配,就会用适当的编解码方式对文件压缩和解压。
选择因素:
(1)数据量小于块大小,考虑压缩和解压缩速度比较快的Snappy/LZO
(2)数据量非常大,考虑支持切片的Bzip2/LZO

2、Map到Reduce中间
在两者中间,肯定要要传输数据,为了减少MapTask和ReduceTask之间的网络IO。
就可以考虑压缩和解压缩快的压缩编码,比如Snappy、LZO。

3、Reduce后(输出端)
这个时候选择要考虑具体需求:
(1)若数据永久保存,考虑压缩率较高的 Bzip2 /  Gzip。
(2)若作为下一个MapReduce输入,要考虑数据量大小和是否支持切片。

10.1.5 参数配置

1、Hadoop引入编码/解码器来支持多种压缩/解压缩算法

压缩格式 对应的编码/解码器
DEFLATE org.apache.hadoop.io.compress.DefaultCodec
gzip org.apache.hadoop.io.compress.GzipCodec
bzip2 org.apache.hadoop.io.compress.BZip2Codec
LZO com.hadoop.compression.lzo.LzopCodec
Snappy org.apache.hadoop.io.compress.SnappyCodec

2、Hadoop中启用压缩,可以通过如下参数进行配置

参数 默认值 阶段 参考建议
io.compression.codecs (在core-site.xml中配置) 无。需要在命令行输入hadoop checknative查看 输入压缩 Hadoop使用文件扩展名判断是否支持某种编解码器
mapreduce.map.output.compress(在mapred-site.xml中配置) false Mapper输出 这个参数设为true启用压缩
mapreduce.map.output.compress.codec(在mapred-site.xml中配置) org.apache.hadoop.io.compress.DefaultCodec Mapper输出 企业多使用LZO或Snappy编解码器在此阶段压缩数据
mapreduce.output.fileoutputformat.compress(在mapred-site.xml中配置) false Reducer输出 这个参数设为true启用压缩
mapreduce.output.fileoutputformat.compress.codec(在mapred-site.xml中配置) org.apache.hadoop.io.compress.DefaultCodec Reducer输出 使用标准工具或者编解码器,如gzip和bzip2

10.2 Hive中开启map输出阶段压缩

一、理论

在Hive中开启 map 输出阶段压缩可以减少 job 中 map 和 Reduce task 间数据传输量。

二、实践

1、开启 hive 中间传输数据压缩功能
hive (mydb)>set hive.exec.compress.intermediate=true;
2、开启 mapreduce 中 map 输出压缩功能
hive (mydb)>set mapreduce.map.output.compress=true;
3、设置 mapreduce 中 map 输出数据的压缩方式
hive (mydb)>set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
4、执行查询语句
hive (mydb)> select count(ename) name from emp;

想查看过程的话记得开启历史服务器
http://hadoop10:8088/ 
先进去,然后点击History 跳转到历史服务器里面查看
自己配置完了查看,最好给历史服务器配置到某个固定的节点。

10.3 Hive中开启Reduce输出阶段压缩

一、理论

在 Hive 中,将输出写入到表中的时候,输出内容同样可以进行压缩。属性 hive.exec.compress.output 控制着这个功能。用户可能需要保持默认设置文件中的默认值false,这样默认的输出就是非压缩的纯文本文件了。用户可以通过在查询语句或执行脚本中设置这个值为 true,来开启输出结果压缩功能。

二、实践

1、开启 hive 最终输出数据压缩功能
hive (mydb)>set hive.exec.compress.output=true;
2、开启 mapreduce 最终输出数据压缩
hive (mydb)>set mapreduce.output.fileoutputformat.compress=true;
3、设置 mapreduce 最终数据输出压缩方式
hive (mydb)> set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
4、设置 mapreduce 最终数据输出压缩为块压缩
hive (mydb)> set mapreduce.output.fileoutputformat.compress.type=BLOCK;
5、测试一下输出结果是否是压缩文件
hive (mydb)> insert overwrite local directory '/home/data/reduceyasuo' select * from emp distribute by deptno sort by empno desc;
6、去对应的地方查看结果
[root@hadoop10 data]# cd reduceyasuo/
[root@hadoop10 reduceyasuo]# ll
total 4
-rw-r--r--. 1 root root 446 Oct 11 11:58 000000_0.snappy
[root@hadoop10 reduceyasuo]# pwd
/home/data/reduceyasuo

10.4 Hive中常见的存储格式

首先 Hive 支持的存储数据的格式主要有 :TEXTFILE 、SEQUENCEFILE 、PARQUET 、 ORC 。

10.4.1 行式存储和列式存储

1、逻辑物理对应图

Hive之存储和压缩_第1张图片

注:图片来源于网络

上图左边为逻辑表,右边第一个为行式存储,第二个为列式存储。

2、行存储和列存储特点

1、行存储特点
当查询满足条件的一整行数据的时候,列存储需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。
2、列存储的特点
列存储每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。

3、Hive中的存储

TEXTFILE 和 SEQUENCEFILE 的存储格式都是基于行存储的
PARQUET 和 ORC 是基于列式存储的

10.4.2 Hive中的存储格式

10.4.2.1 TextFile格式

Hive中的默认格式,为行存储格式,数据不做压缩,磁盘占用大。

10.4.2.2 Parquet格式

仔细看下面的图,它是一个 Parquet 文件的内容,一个文件中可以存储多个行组,文件的首位都是该文件的 Magic Code,用于校验它是否是一个 Parquet 文件
Footer length 记录了文件元数据的大小,通过该值和文件长度可以计算出元数据的偏移量
文件的元数据中包括每一个行组的元数据信息和该文件存储数据的Schema 信息
除此之外,文件中每一个行组的元数据,每一页的开始都会存储该页的元数据

在 Parquet 中, 有三种类型的页:数据页、字典页和索引页。
	数据页用于存储当前行组中该列的值
	字典页存储该列值的编码字典,每一个列块中最多包含一个字典页
	索引页用来存储当前行组下该列的索引,目前 Parquet 中还不支持索引页。

Hive之存储和压缩_第2张图片

Parquet 文件是以二进制方式存储的,自然而然是不可以直接读取的,文件中包括该文件的数据和元数据,所以 Parquet 格式文件是自解析的。
几个重要的概念:

1、行组(Row Group)
每一个行组包含一定的行数,在一个 HDFS 文件中至少存储一个行组
2、列块(Column Chunk)
在一个行组中每一列保存在一个列块中,行组中的所有列连续的存储在这个行组文件中。
一个列块中的值都是相同类型的,不同的列块可以使用不同的算法进行压缩。
3、页(Page)
每一个列块划分为多个页,一个页是最小的编码的单位,在同一个列块的不同页可能使用不同的编码方式。

其实在一般的情况下,在存储 Parquet 数据的时候会按照 Block 大小设置行组的大小,在一般情况下每一个 Mapper 任务处理数据的最小单位是一个 Block块,这样可以把每一个行组由一个 Mapper 任务来处理,从增大任务执行并行度。

10.4.2.2 ORC格式

官网链接:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ORC

Hive之存储和压缩_第3张图片

注:图片来源于网络

ORC 的全称是 Optimied Row Columnar
ORC文件格式是一种Hadoop生态圈中的列式存储格式,它的产生在2013年初,最初产生自Apache Hive,用于降低Hadoop 数据存储空间的和加速 Hive 查询速度。和Parquet 类似,它并不是一个单纯的列式存储格式,是首先根据行分割整个表,在每一行组内进行按列压缩存储。

一些概念的解释:

每个 Orc 文件由 1 个或多个 stripe 组成,每个 stripe 一般情况下为 HDFS 的块大小,每一个 stripe 中包含多条记录,这些记录按照列进行独立存储,和 Parquet中的 row group 的概念其实是类似的。
每个 Stripe 里有三部分组成,分别是 Index Data,Row Data,Stripe Footer

1、Index Data:一个轻量级的 index,默认是每隔 1W 行做一个索引。这里做的索引是记录某行的各字段在 Row Data 中的偏移量
2、Row Data:存的是真实的数据,先取部分行,然后对这些行按列进行存储。对每个列进行了编码,分成多个 Stream 来存储。
3、Stripe Footer:存的是各个 Stream 的类型,长度等等的信息。

10.5 案例测试对比各种存储格式和压缩

TextFile 、 Parquet 、 ORC 对比

1、TextFile格式

1、创建表
create table student_textfile(id int, name string, sex string, age int, department string) row format delimited fields terminated by "," stored as textfile;
2、造数据
以1122660行,大小为25.6m的数据进行测试,student_big.txt文件。
3、加载数据
load data local inpath '/home/data/student_big.txt' into table student_textfile;
4、查看大小
hive (mydb)> dfs -du -h /user/hive/warehouse/mydb.db/student_textfile/student_big.txt;
25.7 M  25.7 M  /user/hive/warehouse/mydb.db/student_textfile/student_big.txt
hive (mydb)> 

2、Parquet格式

1、创建表
create table student_parquet(id int, name string, sex string, age int, department string) row format delimited fields terminated by "," stored as parquet;
2、造数据
以1122660行,大小为25.6m的数据进行测试,student_big.txt文件。
hive (myhive5)> load data local inpath '/home/data/student_big.txt' into table student_parquet;
上面的命令可以给数据导入到student_parquet表的对应的目录下面,但是这种方式只是直接给数据放过去了,没有产生压缩的效果。在hive中使用命令hive (myhive5)> select * from student_parquet;去查询会报错,因为类型不匹配。
3、加载数据
若是误导入可以,使用下面的命令清空
hive (mydb)> truncate table student_parquet;
使用下面的方式导入:
hive (mydb)> insert into table student_parquet select * from student_textfile;
4、查看大小
hive (mydb)> dfs -du -h /user/hive/warehouse/mydb.db/student_parquet;
2.2 M  2.2 M  /user/hive/warehouse/mydb.db/student_parquet/000000_0
hive (mydb)> 

3、ORC格式

1、创建表
create table student_orc(id int, name string, sex string, age int, department string) row format delimited fields terminated by "," stored as orc tblproperties("orc.compress"="NONE");
注意: tblproperties("orc.compress"="NONE"); -- 设置 orc 存储不使用压缩来进行测试
2、造数据
以1122660行,大小为25.6m的数据进行测试,student_big.txt文件。
3、加载数据
hive (mydb)> load data local inpath '/home/data/student_big.txt' into table student_orc;
FAILED: SemanticException Unable to load data to destination table. Error: The file that you are trying to load does not match the file format of the destination table.
hive (mydb)> 
使用下面的方式导入:
hive (mydb)> insert into table student_orc select * from student_textfile;
4、查看大小
hive (mydb)> dfs -du -h /user/hive/warehouse/mydb.db/student_orc;
6.7 M  6.7 M  /user/hive/warehouse/mydb.db/student_orc/000000_0
hive (mydb)> 

10.5测试结论:

Parquet > ORC > TextFile

注意,可能会由于样本的不同导致结果会出现ORC优于Parquet的情况,这都是正常的现象,但是都优于TextFile。

10.6 案例测试对比各种存储格式和压缩结合方式

再来一遍官网链接:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ORC

Hive之存储和压缩_第4张图片

The parameters are all placed in the TBLPROPERTIES (see Create Table). 
翻译过来:
所有关于 ORCFile 的参数都是在 HQL 语句的 TBLPROPERTIES 字段里面设置的。

1、ORC_ZLIB

1、创建表
create table student_orc_zlib(id int, name string, sex string, age int, department string) row format delimited fields terminated by "," stored as orc tblproperties("orc.compress"="ZLIB");
注意: tblproperties("orc.compress"="ZLIB"); -- 设置 orc 存储使用ZLIB压缩来进行测试
2、造数据
以1122660行,大小为25.6m的数据进行测试,student_big.txt文件。
3、加载数据
hive (mydb)> load data local inpath '/home/data/student_big.txt' into table student_orc_zlib;
FAILED: SemanticException Unable to load data to destination table. Error: The file that you are trying to load does not match the file format of the destination table.
hive (mydb)> 
使用下面的方式导入:
hive (mydb)> insert into table student_orc_zlib select * from student_textfile;
4、查看大小
hive (mydb)> dfs -du -h /user/hive/warehouse/mydb.db/student_orc_zlib;
59.5 K  59.5 K  /user/hive/warehouse/mydb.db/student_orc_zlib/000000_0
hive (mydb)> 

2、ORC_SNAPPY

1、创建表
create table student_orc_snappy(id int, name string, sex string, age int, department string) row format delimited fields terminated by "," stored as orc tblproperties("orc.compress"="SNAPPY");
注意: tblproperties("orc.compress"="SNAPPY"); -- 设置 orc 存储使用SNAPPY压缩来进行测试
2、造数据
以1122660行,大小为25.6m的数据进行测试,student_big.txt文件。
3、加载数据
hive (mydb)> insert into table student_orc_snappy select * from student_textfile;
4、查看大小
hive (mydb)> dfs -du -h /user/hive/warehouse/mydb.db/student_orc_snappy;
343.5 K  343.5 K  /user/hive/warehouse/mydb.db/student_orc_snappy/000000_0
hive (mydb)> 

3、Parquet_Snappy

在默认的情况下,Parquet就自带Snappy压缩。压缩之后的文件的名称示例:

part-00000-3c53817b-4608-4e27-a727-f398b94b4ed9-c000.snappy.parquet

操作示例:

1、创建表
create table student_parquet_snappy(id int, name string, sex string, age int, department string) row format delimited fields terminated by "," stored as parquet tblproperties("parquet.compress"="SNAPPY");
注意: tblproperties("orc.compress"="SNAPPY"); -- 设置 parquet 存储使用SNAPPY压缩来进行测试
2、造数据
以1122660行,大小为25.6m的数据进行测试,student_big.txt文件。
3、加载数据
hive (mydb)> insert into table student_parquet_snappy select * from student_textfile;
4、查看大小
hive (mydb)> dfs -du -h /user/hive/warehouse/mydb.db/student_parquet_snappy;
2.2 M  2.2 M  /user/hive/warehouse/mydb.db/student_parquet_snappy/000000_0
hive (mydb)> 

10.6测试结论(在ORC开压缩的情况下):

ORC > Parquet > TextFile

总结:

企业开发当中,hive 的数据存储格式一般选择:orc 或 parquet;压缩方式可以选择 snappy,lzo 等


声明:
        文章中代码及相关语句为自己根据相应理解编写,文章中出现的相关图片为自己实践中的截图和相关技术对应的图片,若有相关异议,请联系删除。感谢。转载请注明出处,感谢。


By luoyepiaoxue2014

微博地址: http://weibo.com/luoyepiaoxue2014 点击打开链接

你可能感兴趣的:(Hive,Hive,大数据)