hive编程

1、压缩格式比较(Hadoop压缩配置)

先放图![在这里插入图片描述](https://img-blog.csdnimg.cn/e8bb48981cd74131bec4c3937f1448cf.png
snappy虽然不可切分,但也是对已生成的文件,可以在mr阶段指定reduce个数控制生成的文件大小

每一个压缩方案都在压缩/解压缩速度和压缩率间进行权衡。BZip2压缩率最高,但是同时需要消耗最多的CPU开销。GZip是压缩率和压缩/解压缩速度上的下一个选择。因此,如果磁盘空间利用率和I/O开销都需要考虑的话,那么这2种压缩方案都是有吸引力的。
LZO和Snappy压缩率相比前面的2种要小但是压缩/解压缩速度要快,特别是解压缩过程。如果相对于磁盘空间和I/O开销,频繁读取数据所需的解压缩速度更重要的话,那么它们将是不错的选择。
在这里插入图片描述

2、中间压缩

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

<property>
 <name>hive.exec.compress.intermediate</name>
 <value>true</value>
 <description> This controls whether intermediate files produced by Hive between
 multiple map-reduce jobs are compressed. The compression codec and other options
 are determined from hadoop config variables mapred.output.compress* </description>
</property>

Hadoop压缩默认的编/解码器是DefaultCodec。可以通过修改属性mapred.map.output.compression.codec的值来修改编/解码器。这是一个Hadoop配置项,可以在 H A D O O P H O M E / c o n f / m a p r e d − s i t e . x m l 文件中或 HADOOP_HOME/conf/mapred-site.xml文件中或 HADOOPHOME/conf/mapredsite.xml文件中或HADOOP_HOME/conf/hive-site.xml文件中进行配置。SnappyCodec是一个比较好的中间文件压缩编/解码器,因为其很好地结合了低CPU开销和好的压缩执行效率:

<property>
 <name>mapred.map.output.compression.codec</name>
 <value>org.apache.hadoop.io.compress.SnappyCodec</value>
 <description> This controls whether intermediate files produced by Hive
 between multiple map-reduce jobs are compressed. The compression codec
 and other options are determined from hadoop config variables
 mapred.output.compress* </description>
</property>

3、最终输出结果压缩

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

<property>
 <name>hive.exec.compress.output</name>
 <value>false</value>
 <description> This controls whether the final outputs of a query
 (to a local/hdfs file or a Hive table) is compressed. The compression
 codec and other options are determined from hadoop config variables
 mapred.output.compress* </description>
</property>

对于其他Hadoop 任务,开启最终输出结果压缩功能的属性是mapred.output.compress。

如果属性hive.exec.compress.output的值设置为true,那么这时需要为其指定一个编解码器。对于输出文件,使用GZip进行压缩是个不错的主意,因为其通常可以大幅度降低文件的大小。但是,需要记住的是GZip压缩的文件对于后面的MapReduce job而言是不可分割的。

4、sequence file存储格式

Sequence file提供了3种压缩方式:NONE、RECORD和BLOCK,默认是RECORD级别(也就是记录级别)。不过,通常来说,BLOCK级别(也就是块级别)压缩性能最好而且是可以分割的。和很多其他的压缩属性一样,这个属性也并非是Hive特有的。用户可以在Hadoop的mapred-site.xml文件中进行定义,或者在Hive的hive-site.xml文件中进行定义,需要的时候,还可以在脚本中或查询语句前进行指定:

<property>
 <name>mapred.output.compression.type</name>
 <value>BLOCK</value>
 <description>If the job outputs are to compressed as SequenceFiles,
 how should they be compressed? Should be one of NONE, RECORD or BLOCK.
 </description>
</property>

5、使用压缩实践

开启一个Hive会话:

hive> SELECT * FROM a;
4     5
3     2
hive> DESCRIBE a;
a     int
b     int

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

hive> set hive.exec.compress.intermediate=true;
hive> CREATE TABLE intermediate_comp_on
  > ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
  > AS SELECT * FROM a;
Moving data to: file:/user/hive/warehouse/intermediate_comp_on
Table default.intermediate_comp_on stats: [num_partitions: 0, num_files: 1,
num_rows: 2, total_size: 8, raw_data_size: 6]
...

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

hive> dfs -ls /user/hive/warehouse/intermediate_comp_on;
Found 1 items
/user/hive/warehouse/intermediate_comp_on/000000_0

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

我们同样可以为中间数据压缩配置其他的编/解码器而不使用默认的编/解码器。下面这个例子,我们选择使用GZip(尽管通常Snappy是更好的选择)。为显示清晰,将下面语句中的第1行分成了2行:

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;
Moving data to: file:/user/hive/warehouse/intermediate_comp_on_gz
Table default.intermediate_comp_on_gz stats:
[num_partitions: 0, num_files: 1, num_rows: 2, total_size: 8, raw_data_size:6]

hive> dfs -cat /user/hive/warehouse/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;
Moving data to: file:/tmp/hive-edward/hive_2012-01-15_11-11-01_884_.../-ext-10001
Moving data to: file:/user/hive/warehouse/final_comp_on
Table default.final_comp_on stats:
[num_partitions: 0, num_files: 1, num_rows: 2, total_size: 16, raw_data_size:6]

hive> dfs -ls /user/hive/warehouse/final_comp_on;
Found 1 items
/user/hive/warehouse/final_comp_on/000000_0.deflate

输出信息中的表统计信息显示total_size(总大小)是16B,但是raw_data_size(裸数据)是6B,多出的存储空间是被deflate算法消耗了。同时我们可以看到,输出的文件后缀名是.deflate。

不推荐使用cat命令来查看这个压缩文件,因为用户只能看到二进制输出。不过,Hive可以正常地查询这个数据:

hive> dfs -cat /user/hive/warehouse/final_comp_on/000000_0.deflate;
... UGLYBINARYHERE ...

hive> SELECT * FROM final_comp_on;
4     5
3     2

这种无缝的处理压缩文件的能力并非是Hive独有的,实际上,这里是使用了Hadoop的TextInputFormat进行的处理。尽管在这种情况下这个命名有些令人混淆,但是TextInputFormat可以识别文件后缀名为.deflate或.gz的压缩文件,并且可以很轻松地进行处理。Hive无需关心底层的文件是否是压缩的,以及是使用何种压缩方案进行压缩的。

下面我们改变下输出结果压缩所使用的编解码器,然后看下结果(这里语句的第2行为了显示清晰,也分成2行了):

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;
Moving data to: file:/user/hive/warehouse/final_comp_on_gz
Table default.final_comp_on_gz stats:
[num_partitions: 0, num_files: 1, num_rows: 2, total_size: 28, raw_data_ size:6]

hive> dfs -ls /user/hive/warehouse/final_comp_on_gz;
Found 1 items
/user/hive/warehouse/final_comp_on_gz/000000_0.gz

正如用户可以看到的,输出文件夹下现在包含了零个或多个.gz文件。Hive提供了在Hive shell中执行像zcat这样的本地命令的快速方法。通过!符号,Hive可以执行外部的命令,直到返回结果。

zcat是一个命令行实用程序,用来解压缩,并进行输出显示:

hive> ! /bin/zcat /user/hive/warehouse/final_comp_on_gz/000000_0.gz;
4     5
3     2
hive> SELECT * FROM final_comp_on_gz;
OK
4     5
3     2
Time taken: 0.159 seconds

使用这种输出压缩能够完成那种很小,操作起来很快的文件的二进制压缩。不过,回想一下,输出文件的个数是和处理数据所需要的mapper个数或reducers个数有关的。在最坏的情况下,可能最终结果是文件夹中只产生了一个大的压缩文件,而且是不可分割的。这意味着后续步骤并不能并行地处理这个数据。解决这个问题的答案就是使用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;
Moving data to: file:/user/hive/warehouse/final_comp_on_gz_seq
Table default.final_comp_on_gz_seq stats:
[num_partitions: 0, num_files: 1, num_rows: 2, total_size: 199, raw_data_ size: 6]

hive> dfs -ls /user/hive/warehouse/final_comp_on_gz_seq;
Found 1 items
/user/hive/warehouse/final_comp_on_gz_seq/000000_0

Sequence file是二进制格式的,但是,我们可以很容易地查询文件头。通过查看文件头可以确认结果是否是我们需要的(为方便显示,输出格式进行了调整):

hive> dfs -cat /user/hive/warehouse/final_comp_on_gz_seq/000000_0;
SEQ[]org.apache.hadoop.io.BytesWritable[]org.apache.hadoop.io.BytesWritable[]
 org.apache.hadoop.io.compress.GzipCodec[]

因为sequence file中嵌入的元数据信息以及Hive元数据信息,Hive无需任何特别的设置就可以查询这张表。Hadoop同样提供了dfs –text命令来从sequence file文件中去除掉文件头和压缩,然后显示裸数据:

hive> dfs -text /user/hive/warehouse/final_comp_on_gz_seq/000000_0;
    4     5
    3     2
hive> select * from final_comp_on_gz_seq;
OK
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;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值