Hive压缩方案
目录
一、测试背景
由于集群数据量大,需要进行压缩,根据Hive官方提供的几种压缩格式分别进行写入,读取,OLAP计算的性能测试,以求找到最好的压缩格式。
二、测试概述
1、数据来源:采用生产上数据抽样,大小为9.8G。原始数据表格式为textfile格式。
2、测试平台:公司CDH4.5.9测试平台。
3、测试方法:将textfile文件通过脚本自动录入到Hive里,形成大表。
4、从大表创建基于各种不同压缩方式。
5、查看是否支持压缩命令
6、根据业务应用场景选择textfile+Gzip格式进行各种压缩算法测试。
命令检测:hadoop checknative
三、HIVE的几种文件格式对比
3.1、Textfile格式
默认的文件格式,行存储。建表时不指定存储格式即为textfile,导入数据时把数据文件拷贝至hdfs不进行处理。
优点:
1、最简单的数据格式,便于和其他工具(Pig, grep, sed, awk)共享数据,便于查看和编辑;加载较快。
缺点:
- 耗费存储空间,I/O性能较低;Hive不进行数据切分合并,不能进行并行操作,查询效率低。
适用于小型查询,查看具体数据内容的测试操作。
3.2、sequencefile格式
含有键值对的二进制文件,行存储。
优点:
1、可压缩、可分割,优化磁盘利用率和I/O;可并行操作数据,查询效率高;
缺点:
- 存储空间消耗最大;对于Hadoop生态系统之外的工具不适用,需要通过text文件转化加载。
适用于数据量较小、大部分列的查询。
3.3、rcfile格式
行列式存储。先将数据按行分块,同一个record在一个块上,避免读一条记录需要读多个block;然后块数据列式存储。
优点:
1、可压缩,高效的列存取;查询效率较高。
缺点:
1、加载时性能消耗较大,需要通过text文件转化加载;读取全量数据性能低。
3.4、orcfile格式
优化后的orcfile,行列式存储。优缺点与rcfile类似,查询效率最高。适用于Hive中大型的存储、查询。
四、形式存储和列式存储的比较
4.1、行式存储优点
- 相关的数据是保存在一起,比较符合面向对象的思维,因为一行数据就是一条记录。
- 这种存储格式比较方便进行INSERT/UPDATE操作。
4.2、行式存储缺点
1、如果查询只涉及某几个列,它会把整行数据都读取出来,不能跳过不必要的列读取。当然数据比较少,一般没啥问题,如果数据量比较大就比较影响性能。
2、由于每一行中,列的数据类型不一致,导致不容易获得一个极高的压缩比,也就是空间利用率不高。
3、不是所有的列都适合作为索引。
4.3、列式存储优点
- 查询时,只有涉及到的列才会被查询,不会把所有列都查询出来,即可以跳过不必要的列查询。
- 高效的压缩率,不仅节省储存空间也节省计算内存和CPU。
- 任何列都可以作为索引。
4.4列式存储的缺点
- INSERT/UPDATE很麻烦或者不方便。
- 不适合扫描小量的数据。
五、压缩算法比较
序号 | 压缩格式 | 算法 | 多文件 | 可分割性 | 工具 | 工具压缩后的扩展名 |
1 | DEFLATE | DEFLATE | 不支持 | 不支持 | 无 | .deflate |
2 | Gzip | DEFLATE | 不支持 | 不支持 | gzip | .gz |
3 | Bzip2 | bzip2 | 不支持 | 支持 | bzip2 | .bz2 |
4 | LZO | LZO | 不支持 | 支持 | lzop | .lzo |
5 | LZ4 | 无 | 无 | 无 | 无 | 无 |
6 | Snappy | 无 | 无 | 无 | 无 | 无 |
六、实际压缩操作
6.1、文本文件Gzip压缩
Hive开启文本文件Gzip压缩模式:
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
插入数据:
insert into table etl_termtype_latest_txtfile partition (p_day='20190114’) select `mdn`,`imsi`,`province`,`city`,`factory`,`term_type`,`id_code1`,`id_code12`,`linetime`,`firstregistertime` from etl_termtype_latest;
查看两张表的大小对比:
hadoop fs -du -h /DATA/FZP/ETL/ETL_TERMTYPE_LATEST
hadoop fs -du -h /DATA/FZP/ETL/ETL_TERMTYPE_LATEST_TXTFILE
删除源表:
drop table ETL_TERMTYPE_LATEST;
修改表名:
alter table etl_termtype_latest_txtfile rename to etl_termtype_latest;
6.2、文本文件Deflate压缩
--设置压缩类型为Deflate压缩
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.DefaultCodec;
6.3、文本文件Bzip2压缩
--设置压缩类型为Bzip2压缩:
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.BZip2Codec;
6.4、文本文件Lzo压缩
--设置为LZO压缩
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=com.hadoop.compression.lzo.LzopCodec;
6.5、文本文件Lz4压缩
--设置为LZ4压缩
SET hive.exec.compress.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.Lz4Codec;
6.6、文本文件Snappy压缩
--设置Snappy压缩
SET hive.exec.compress.output=true;
SET mapred.compress.map.output=true;
SET mapred.output.compress=true;
SET mapred.output.compression=org.apache.hadoop.io.compress.SnappyCodec;
SET mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
SET io.compression.codecs=org.apache.hadoop.io.compress.SnappyCodec;
七、结果统计数据
测试数据9.8G/87729200
性能测试结果:
存储压缩格式/Textfile | Gzip | Deflate | Bzip2 | Lzo | lz4 | Snappy |
数据压缩大小 | 3.3G | 3.3G | 2.3G | 3.3G | 5.5G | 5.8G |
压缩存储时间 | 88.901s | 234.404s | 292.276s | 264.352s | 179.69s | 178.994s |
SQL查询响应速度 | 43.07s | 37.722s | 34.339s | 40.422s | 37.504s | 35.243s |
是否明文文本 | 是 | 否 | 否 | 否 | 否 | 否 |
现网更改涉及操作 | 无 | 无 | 无 | 无 | 无 | 无 |
是否并行处理 | 无 | 无 | 无 | 无 | 无 | 无 |
八、总结
1、经过测试put或者load数据到hive表不支持压缩。
2、经过测试hive终端关闭需要重新开启压缩模式,改成全局需要通过修改配置文件重启永久生效,会影响到程序的读写。
3、数据压缩不会产生KB大小文件数。
4、文件的大小是根据压缩格式规定了压缩的比率,比率确定就无法改。
5、经过测试确定选择局部压缩方案,开启Hive压缩模式终端不能退出。新建一张Hive表开启压缩模式,insert插入数据完成,删除旧表。
九、注解
只有TEXTFILE表能直接加载数据,和external外部表直接加载数据,都只能用TEXTFILE表。 更深一步,hive默认支持的压缩文件(hadoop默认支持的压缩格式),也只能用TEXTFILE表直接读取。其他格式不行。可以通过TEXTFILE表加载后insert到其他表中。 换句话说,SequenceFile、RCFile、ORCfile表不能直接加载数据需要进行格式转换,数据要先导入到textfile表,再从textfile表通过insert select from 导入到SequenceFile,RCFile,ORCFile表。 SequenceFile、RCFile,ORCFile表的源文件不能直接查看,在hive中用select看。ORCFile源文件可以用 hive --service rcfilecat /xxxxxxxxxxxxxxxxxxxxxxxxxxx/000000_0查看,但是格式不同。
十、Hive压缩文件合并
#在Map-only的任务结束时合并小文件
set hive.merge.mapfiles = true
#在Map-Reduce的任务结束时合并小文件
set hive.merge.mapredfiles = true
#合并文件的大小
set hive.merge.size.per.task = 6697411824
#当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
set hive.merge.smallfiles.avgsize=334870912
-- 每个Map最大输入大小,决定合并后的文件数
#Mapred.max.split.size指的是数据的最大分割单元大小。
set mapred.max.split.size=6697411824;
-- 一个节点上split的至少的大小 ,决定了多个data node上的文件是否需要合并
#Mapred.min.split.size指的是数据的最小分割单元大小。
set mapred.min.split.size.per.node=334870912;
-- 一个交换机下split的至少的大小,决定了多个交换机上的文件是否需要合并
set mapred.min.split.size.per.rack=334870912;
-- 执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
十一、Gzip压缩同样内容文件大小不一样
一份数据:两种传输方式进行收集,有多台数据采集节点或者多个数据源。
两种方式:一种是从一次多个采集节点或者多个数据将数据拷贝过来合并为一个文件,另外一种是多个采集节点或者数据源同时向汇总端发送数据,最后合并为一个文件。
两种方式的不同:汇总后的数据都是一样,但是顺序会不一样,使用Gzip命令压缩合并文件最终显示压缩后的文件大小不一样。
由此可见同样的数据用gzip压缩比较大小需要保证顺序一致,压缩算法导致顺序不同压缩的结果不同。