Hive之——其他文件格式和压缩方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l1028386804/article/details/88430637

转载请注明出处:https://blog.csdn.net/l1028386804/article/details/88430637

确定安装编解码器
Hive中可以通过set命令查看Hive配置文件中或Hadoop配置文件中配置的值。

hive -e "set io.compression.codec"

开启中间压缩
对中间数据进行压缩可以减少job中map和reduce task间的数据传输量。对于中间数据压缩,选择一个低CPU开销的编/解码器要比选择一个压缩率高的编/解码器要重要的多。属性hive.exec.compress.intermediate的默认值是false,如果要开启中间压缩,就需要将这个属性值修改为默认值true:

<property>
	<name>hive.exec.compress.intermediate</name>
	<value>true</value>
</property>

Hadoop压缩默认的编/解码器是DefaultCodec。可以通过修改属性mapred.map.output.compression.codec的值来修改编/解码器。这是一个Hadoop配置项,可以在$HADOOP_HOME/conf/mapred-site.xml或$HIVE_HOME/conf/hive-site.xml文件中配置。SnappyCodec是一个比较好的中间文件压缩编/解码器

<property>
	<name>mapred.map.output.compression.codec</name>
	<value>org.apache.hadoop.io.compress.SnappyCodec</value>
</property>

最终输出结果压缩
当Hive将输出写入到表时,输出内容同样可以进行压缩。属性hive.exec.compress.output控制着这个功能,默认值为false。

<property>
	<name>hive.exec.compress.output</name>
	<value>true</value>
</property>

开启后,需要指定一个编解码器,建议是GZip

<property>
	<name>mapred.output.compression.codec</name>
	<value>org.apache.hadoop.io.compress.GzipCodec</value>
</property>

sequence file存储格式
sequence file存储格式可以将一个文件划分成多个块,然后采用一种可分割的方式对快进行压缩。
使用sequence file存储格式:

create table a_sequence_file_table stored as sequencefile;

sequence file提供了3中压缩方式:None、RECORD、BLOCK,默认是RECORD级别(也就是记录级别)。不过,BLOCK(块级别)压缩性能最好而且是可以分割的。
如果想设置为BLOCK方式,可以在Hadoop的mapred-site.xml或者在hive-site.xml文件中进行定义,需要的时候,可以在脚本中或查询语句前进行指定:

<property>
	<name>mapred.output.compression.type</name>
	<value>BLOCK</value>
</property>

使用压缩实践

创建数据库test

create database test;

创建表a

hive> create table if not exists a(a int, b int) row format delimited fields terminated by '\t';

查看表结构:

hive> desc a;
OK
a                       int                                         
b                       int                                         
Time taken: 0.068 seconds, Fetched: 2 row(s)

装载数据

hive> load data local inpath '/root/test.txt' into table a;

查看数据:

hive> select * from a;
OK
4       5
3       2
Time taken: 1.915 seconds, Fetched: 2 row(s)

首先,开启中间数据压缩功能,不会影响到最终输出结果。但是从job计数器信息看,可以发现这个job中间传送的数据量变小了,因为shuffle sort(混洗排序)数据被压缩了:

set hive.exec.compress.intermediate=true;

create table intermediate_comp_on
row format delimited fields terminated by '\t'
as select * from a;

和预期的一样,中间数据压缩没有影响到最终的输出,最终的数据结果仍然是非压缩的

hive> dfs -ls /user/hive/warehouse/test.db/intermediate_comp_on;
Found 1 items
-rwxr-xr-x   1 root supergroup          8 2019-03-12 13:49 /user/hive/warehouse/test.db/intermediate_comp_on/000000_0

hive> dfs -cat /user/hive/warehouse/test.db/intermediate_comp_on/000000_0;
4       5
3       2

接下来我们使用GZip编/解码器。

hive> set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.GZipCodec;
hive> set hive.exec.compress.intermediate=true;
hive> create table intermediate_comp_on_gz row format delimited fields terminated by '\t' as select * from a;
hive> dfs -cat /user/hive/warehouse/test.db/intermediate_comp_on_gz/000000_0;
4       5
3       2

接下来,开启输出结果压缩:

hive> set hive.exec.compress.output=true;
hive> create table final_comp_on row format delimited fields terminated by '\t' as select * from a;
hive> dfs -ls /user/hive/warehouse/test.db/final_comp_on;
Found 1 items
-rwxr-xr-x   1 root supergroup         16 2019-03-12 14:01 /user/hive/warehouse/test.db/final_comp_on/000000_0.deflate

hive> select * from final_comp_on;
OK
4       5
3       2
Time taken: 0.12 seconds, Fetched: 2 row(s)

接下来,将输出结果的编解码器修改为gzip

hive> set hive exec.compress.output=true;
hive> set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
hive> create table final_comp_on_gz row format delimited fields terminated by '\t' as select * from a;
hive> dfs -ls /user/hive/warehouse/test.db/final_comp_on_gz;
Found 1 items
-rwxr-xr-x   1 root supergroup         28 2019-03-12 14:07 /user/hive/warehouse/test.db/final_comp_on_gz/000000_0.gz
hive> select * from final_comp_on_gz;
OK
4       5
3       2
Time taken: 0.122 seconds, Fetched: 2 row(s)

输出文件的个数适合处理数据所需要的mapper个数或reducer个数有关的。在最坏的情况下,可能最终结果是文件夹中只产生了一个大的压缩文件,而且是不可分割的。这意味着后续步骤并不能并行的处理这个数据。解决这个问题的答案就是使用sequence_file:

hive> set mapred.output.compression.type=BLOCK;
hive> set hive.exec.compress.output=true;
hive> set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
hive> create table final_comp_on_gz_seq row format delimited fields terminated by '\t' stored as sequencefile as select * from a;
hive> dfs -text /user/hive/warehouse/test.db/final_comp_on_gz_seq/000000_0;
        4       5
        3       2

最后,使用直接数据压缩和最终数据压缩,而且使用不同压缩编/解码器的sequence file。

hive> set mapred.map.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
hive> set hive.exec.compress.intermediate=true;
hive> set mapred.output.compression.type=BLOCK;
hive> set hive.exec.compress.output=true;
hive> set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
hive> create table final_comp_on_gz_int_compress_snappy_seq row format delimited fields terminated by '\t' stored as sequencefile as select * from a;

hive> dfs -ls /user/hive/warehouse/test.db/final_comp_on_gz_int_compress_snappy_seq;
Found 1 items
-rwxr-xr-x   1 root supergroup        247 2019-03-12 15:48 /user/hive/warehouse/test.db/final_comp_on_gz_int_compress_snappy_seq/000000_0
hive> dfs -text /user/hive/warehouse/test.db/final_comp_on_gz_int_compress_snappy_seq/000000_0;
        4       5
        3       2

存档分区
一个HAR文件就像在HDFS文件系统中的一个TAR文件一样是一个单独的文件。不过,其内部可以存放多个文件和文件夹。通过将分区下的文件归档成一个巨大的,但是同时可以被Hive访问的文件,可以减轻NameNode的压力。不过其缺点是,HAR文件查询效率不高;同时,HAR文件并非是压缩的,因此也不会节约存储空间。

创建一个分区表:

hive> create table hive_text(line string) partitioned by (folder string);
hive> alter table hive_text add partition(folder='docs');
hive> load data local inpath '${env:HIVE_HOME}/NOTICE' into table hive_text partition(folder='docs');
Loading data to table test.hive_text partition (folder=docs)
OK
Time taken: 1.389 seconds

hive> load data local inpath '${env:HIVE_HOME}/RELEASE_NOTES.txt' into table hive_text partition(folder='docs');
Loading data to table test.hive_text partition (folder=docs)
OK
Time taken: 0.596 seconds

hive> select * from hive_text where line like '%hive%' limit 2;

hive> dfs -ls /user/hive/warehouse/test.db/hive_text/folder=docs;
Found 2 items
-rwxr-xr-x   1 root supergroup        230 2019-03-12 17:22 /user/hive/warehouse/test.db/hive_text/folder=docs/NOTICE
-rwxr-xr-x   1 root supergroup        313 2019-03-12 17:23 /user/hive/warehouse/test.db/hive_text/folder=docs/RELEASE_NOTES.txt

alter table ... archive partition语句将表转化成一个归档表:
这里,我用的是Hadoop-2.9.2和Hive-2.3.4
首先在HIVE_HOME目录auxlib
然后将$HADOOP_HOME/share/hadoop/tools/lib/hadoop-archives-2.9.2.jar 复制到 $HIVE_HOME/auxlib目录下。

hive> set hive.archive.enabled=true;
hive> alter table hive_text archive partition(folder='docs');
hive> dfs -ls /user/hive/warehouse/test.db/hive_text/folder=docs;
Found 1 items
drwxr-xr-x   - root supergroup          0 2019-03-12 17:50 /user/hive/warehouse/test.db/hive_text/folder=docs/data.har

可以看到两个文件变成了Hadoop归档文件(也就是HAR文件)。

alter table ... unarchive partition 命令可以将HAR中的文件提取出来然后重新放置到HDFS中。

hive> alter table hive_text unarchive partition(folder='docs');
hive> dfs -ls /user/hive/warehouse/test.db/hive_text/folder=docs;
Found 3 items
drwxr-xr-x   - root supergroup          0 2019-03-12 17:55 /user/hive/warehouse/test.db/hive_text/folder=docs/.hive-staging_hive_2019-03-12_17-50-13_474_3076666758201858070-1
-rw-r--r--   1 root supergroup        230 2019-03-12 17:55 /user/hive/warehouse/test.db/hive_text/folder=docs/NOTICE
-rw-r--r--   1 root supergroup        313 2019-03-12 17:55 /user/hive/warehouse/test.db/hive_text/folder=docs/RELEASE_NOTES.txt

猜你喜欢

转载自blog.csdn.net/l1028386804/article/details/88430637
今日推荐