深入学习《Programing Hive》:数据压缩

Hive使用的是Hadoop的文件系统和文件格式,比如TEXTFILE,SEQUENCEFILE等。
         在Hive中对中间数据或最终数据数据做压缩,是提高数据吞吐量和性能的一种手段。对数据做压缩,可以大量减少磁盘的存储空间,比如基于文本的数据文件, 可以将文件压缩40%或更多,同时压缩后的文件在磁盘间传输和I/O也会大大减少;当然压缩和解压缩也会带来额外的CPU开销,但是却可以节省更多的I /O和使用更少的内存开销。
         Hadoop jobs作业,往往是I/O密集型的,而非CPU集型的。数据压缩对I/O密集型的作业带来大大的性能提升,但是如果用户的jobs作业时CPU密集型 的,那么在使用压缩就会降低性能,这就要用户对作业的类型做判断,权衡是否要对数据做压缩。
     
         选择合适的编解码器
         对数据做压缩,可以最大程度的减少文件所需的磁盘空间和网络I/O的开销,但对数据做压缩和解压缩总会增加CPU的开销,故最好对那些I/O密集型的作业使用数据压缩——这样的作业会有富余的CPU资源,或者对那些磁盘空间不富裕的系统。
         Hadoop默认支持Gzip和BZip2的解压缩方式,包括原生的linux解压缩库。Snappy压缩在最近的Hive版本中才被添加的压缩算法,如果您使用的是Hive不支持Snappy的话,用户就要手动添加。过去经常使用的是LZO压缩算法。
         那么,为什么要使用不同的压缩算法呢?它们都有什么区别呢?BZip2有最高的压缩比但也会带来更高的CPU开销,Gzip较BZip2次之;如果基于磁盘利用率和I/O考虑,这两个压缩算法都是比较有吸引力的算法。
         LZO和Snappy算法有更快的解压缩速度,如果在关注数据解压多于磁盘利用率和I/O开销的场景中,它们都是不错的选择。LZO和Snappy在压缩数据上大致相当,但Snappy算法在解压速度上要较LZO更快。                 
         在选择解压缩算法时,另外一个比较重要的考虑就是压缩格式是否是支持可分割的。Hadoop的会将大文件分割成HDFS block(默认64MB)大小的splits分片,每个分片对应一个Mapper程序。在这几个压缩算法中,只有BZip2和LZO提供block级的压缩,而Gzip和Snappy则不支持。
         Snappy压缩算法时首选。

         打开Hive(即由mappe产生的)中间数据文件的压缩功能
         HiveQL语句最终会被编译成Hadoop的Mapreduce job,开启Hive的中间数据压缩功能,就是在MapReduce的shuffle阶段对mapper产生的中间结果数据压缩。在这个阶段,优先选择一个低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 mutiple map-redece job are compressed.The compression codec and other options are determined from hadoop config variables mared.output.compress*</description>  
</property>  


         具体的压缩算法参数配置,这是一个hadoop的配置参数,可以在Hadoop的$HADOOP_HOME/conf/marred-site.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 mutiple map-redece job are compressed.The compression codec and other options are determined from hadoop config variables mared.output.compress*</description>  
</property>  


  
         最Hive的数据文件压缩
         用户可以对最终生成的Hive表的数据通常也需要压缩。参数hive.exec.compress.output控制这一功能的激活与禁用。用户可以通过节本来打开这个功能,同样也可以在XML配置文件中将该功能配置成全局变量:

<property>  
    <name>hive.exec.compress.output</name>  
    <value>true</value>  
    <description>This controls whether the final outpus 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 mared.output.compress*</description>  
</property>  


         将hive.exec.compress.output参数设置成true后,然后选择一个合适的编解码器,如选择SnappyCodec:

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



         Sequence Files
         压缩数据文件可以节省磁盘空间,但是在Hadoop中有些原生压缩文件的缺点之一就是不支持分割。支持分割的文件可以并行的有多个mapper程序处理大数据文件,大多数文件不支持可分割是因为这些文件只能从头开始读。
         Sequence File是可分割的文件格式,支持Hadoop的block级压缩。这样,我们就可以将Hive表存储定义成SEQUENCEFILE:

CREATE TABLE a_sequence_file_table SORTED AS SEQUENCEFILE;  


         Sequence Files有三个不同的压缩选项:NOE,RECORD和BLOCK。RECORD是默认选项,通常BLOCK会带来较RECORD更好的压缩性能。同很 多其他压缩选项一样,这个压缩类型参数不是Hive特有的,需要在Hadoop中或在每一个Hive查询脚本中2设置。

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

相关推荐