文件压缩主要有两方面的好处:一方面节省文件存储空间;另一方面加速网络数据传输或磁盘读写。当处理大规模的数据时这些效果提升更加明显,因此我们需要仔细斟酌压缩在Hadoop环境下的使用。
 
目前已经存在很多压缩格式、工具和算法,各有特点,如下图:
 
 
说明:
a. DEFLATE是一种压缩算法,标准实现是zlib,尚没有命令行工具支持。一般情况下使用gzip,相对于DEFLATE而言有额外的头部和尾部。文件扩展名.deflate是一个Hadoop的约定。
 
b. LZO文件经过预处理被索引之后是可以支持切片的。
 
所有的压缩算法都存在空间与时间的权衡:更快的压缩速率和解压速率是以牺牲压缩率为代价的。通常的命令行工具会提供九种不同的权衡选项:-1意味着更快的压缩速率;-9意味着更高的压缩率。如:gzip -1 file意味着使用更快的压缩算法创建压缩文件file.gz。
 
不同的压缩算法拥有不同的压缩特性:
 
gzip是一种常规的压缩工具,空间与时间得到很好的权衡;
 
bzip2压缩率高于gzip,但压缩速度较慢;解析速度优于它的压缩速度,但还是较其它压缩算法偏慢;
 
LZO、LZ4和Snappy相对于gzip而言压缩速度得到很大提升,但没有gzip的压缩率高;而Snappy和LZ4相对于LZO而言在解压速率方面有明显的提升。
 
“Splittable”指示压缩格式是否支持切片,即是否可以在数据流中随意寻址读取数据,可切片的压缩格式非常适合MapRedcue。
 
Codecs
 
Codec是实现特定压缩/解压缩算法的编码解码器。Hadoop Codec必须实现CompressionCodec接口,如下:
 
public interface CompressionCodec {
CompressionOutputStream createOutputStream(OutputStream out) throws IOException;
CompressionOutputStream createOutputStream(OutputStream out, Compressor compressor) throws IOException;
Class<? extends Compressor> getCompressorType();
Compressor createCompressor();
CompressionInputStream createInputStream(InputStream in) throws IOException;
CompressionInputStream createInputStream(InputStream in, Decompressor decompressor) throws IOException;
Class<? extends Decompressor> getDecompressorType();
Decompressor createDecompressor();
String getDefaultExtension();
}
 可用的Codec如下:
 
 
LZO库是基于GPL协议的,没有被包含在Apache的发布版中,需要独立下载。
 
Compressing and decompressing streams with CompressionCodec
 
CompressionCodec有两个方法可以帮助我们方便的压缩或解压数据。压缩数据时使用createOutputStream(OutputStream out)获取压缩输出流,我们将未压缩的数据写入该流,它会帮我们压缩数据后写出至底层的数据流out;相反地,解析数据时使用createInputStream(InputStream in)获取解压缩输入流,通过它我们可以从底层的数据流中读取解压后的数据。
 
CompressionOutputStream、CompressionInputStream与java.util.zip.DeflaterOutputStream、java.util.zip.DeflaterInputStream类似,但是前者支持重置内部的压缩器(Compressor)与解压缩器(Decompressor)状态。如果应用程序需要将数据流中的数据一部分一部分地压缩成“块”的形式,每次压缩完一个“块”之后都需要重置压缩器(Compressor)的状态才可以压缩下一“块”的数据,解压缩时同理。
 
 
这个应用程序读取标准输入流中的数据,使用指定的压缩算法将数据压缩后写出至标准输出流。程序运行时需要提供一个命令行参数:CompressionCodec全限定类名。可以使用下面的命令进行验证:
 
echo "Text" | hadoop StreamCompressor org.apache.hadoop.io.compress.GzipCodec | gunzip
Text
 
Inferring CompressionCodecs using CompressionCodecFactory
 
当我们仅仅需要处理一种特定格式的压缩文件时,我们可以简单的根据这个压缩文件的后缀名决定使用哪个Codec进行数据读取(上述两张图分别给出文件后缀名与压缩格式的对应关系,以及压缩格式与Codec的对应关系);当我们的应用程序需要兼容多种压缩格式时,就需要有一种机制帮助我们根据压缩文件后缀名透明地帮助我们选取合适的Codec。
 
CompressionCodecFactory getCodec()方法可以根据我们提供的一个文件路径(文件名称带有后缀)返回匹配CompressionCodec。
 
CompressionCodecFactory实例初始化时,会在构造方法中维护文件后缀名与CompressionCodec的映射关系,代码如下:
 
 
其中,getCodecClasses返回我们配置(io.compression.codecs)的所有CompressionCodec实例,然后通过addCodec()方法维护映射关系。如果我们没有配置任何需要支持的CompressionCodec,则默认添加GzipCodec,DefaultCodec。
 
 
可以看出文件后缀名是通过CompressionCodec getDefaultExtension()方法获取的,而且经过字符串逆转处理,每一个CompressionCodec实例都会有一个getDefaultExtension()方法,返回此CompressionCodec实例对应的文件后缀名,如GzipCodec:
 
 
addCodec方法很重要的一部分工作就是维护文件后缀名与CompressionCodec之间的映射关系codecs,
 
 
源码注释也强调这里codecs的实现有点“过度”(SortedMap),如果直接使用HashMap表示文件后缀名与CompressionCodec之间的映射关系是不是更简单?
 
 
因为“过度”的使用SortedMap,getCodec的实现也略有点复杂,读者可自行理解,核心思想依然是根据传入的文件路径获取文件后缀名,然后在codecs中寻找匹配的CompressionCodec。
 
CompressionCodecFactory使用示例如下:
 
 
可以看出我们并不需要在程序中显示指定使用哪个CompressionCodec,而是由CompressionCodecFactory帮助我们根据文件后缀名自动推断出相应的CompressionCodec,极大地增强应用程序在处理压缩文件时的通用性。
 
Native libraries
 
Hadoop的压缩库通常会有两种实现,一种是Java实现,另一种是本地库,就性能而言本地库在压缩和解压方面更具优势。比如gzip,使用本地库相比于Java实现,压缩时间可以提高10%,解压缩时间可以提高50%。
 
 
默认情况下,Hadoop会自动在本地库路径(java.library.path)下查询并加载合适的本地库实现,我们可以通过设置属性io.native.lib.available为false禁用本地库,此时内建的Java实现将被使用。
 
CodecPool
 
在应用程序中如果需要使用本地库进行大量的压缩、解压工作,可以考虑通过使用CodecPool重用压缩器(Compressor)和解压缩器(Decompressor),从而避免频繁创建这些对象带来的大量开销。
 
 
 
 
 

Hadoop Compression的更多相关文章

  1. Spark on Yarn出现hadoop.compression.lzo.LzoCodec not found问题发现及解决

    问题描述: spark.SparkContext: Created broadcast 0 from textFile at WordCount.scala:37 Exception in threa ...

  2. [Compression] Hadoop 压缩

    0. 说明 Hadoop 压缩介绍 && 压缩格式总结 && 压缩编解码器测试 1. 介绍 [文件压缩的好处] 文件压缩的好处如下: 减少存储文件所需要的磁盘空间 加速 ...

  3. hadoop安装遇到的各种异常及解决办法

    hadoop安装遇到的各种异常及解决办法 异常一: 2014-03-13 11:10:23,665 INFO org.apache.hadoop.ipc.Client: Retrying connec ...

  4. Hadoop安装lzo实验

    参考http://blog.csdn.net/lalaguozhe/article/details/10912527 环境:hadoop2.3cdh5.0.2 hive 1.2.1 目标:安装lzo ...

  5. hadoop core-site.xml

    <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text ...

  6. Hadoop配置文件

    部分内容参考:http://www.linuxqq.net/archives/964.html  http://slaytanic.blog.51cto.com/2057708/1100974/ ht ...

  7. Hadoop使用lzo压缩格式

    在hadoop中搭建lzo环境: wget http://www.oberhumer.com/opensource/lzo/download/lzo-2.06.tar.gz export CFLAGS ...

  8. 使用yum安装CDH Hadoop集群

    使用yum安装CDH Hadoop集群 2013.04.06 Update: 2014.07.21 添加 lzo 的安装 2014.05.20 修改cdh4为cdh5进行安装. 2014.10.22  ...

  9. [大牛翻译系列]Hadoop(20)附录A.10 压缩格式LZOP编译安装配置

    附录A.10 LZOP LZOP是一种压缩解码器,在MapReduce中可以支持可分块的压缩.第5章中有一节介绍了如何应用LZOP.在这一节中,将介绍如何编译LZOP,在集群做相应配置. A.10.1 ...

随机推荐

  1. 重启adb服务

    通过命令提示符的方式来重启ADB服务的步骤如下: 1.输入adb kill-server并按下Enter键. 2.输入adb start-server并按下Enter键. 这样将会顺利地关闭ADB服务 ...

  2. Qt国际化详细介绍,中文乱码以及解决方案

    Qt国际化的一般步骤 运行 lupdate,从应用程序的代码中提取所有界面上的可见字符.        这些可见字符必须被 tr() .QCoreApplication::translate().Qt ...

  3. Gradle Import Wizard--官方文档

    Last updated and checked to work with version 3.0.0 of the tools This tutorial will take you through ...

  4. 在浏览器地址栏按回车、F5、Ctrl+F5刷新网页的区别--转

    其中,在地址栏按回车又分为两种情况.一是请求的URI在浏览器缓存中未过期,此时,使用Firefox的firebug插件在浏览器里显示的HTTP请求消息头如下: Host    192.168.3.17 ...

  5. SpringMVC中文乱码

    刚刚构建的SpringMVC项目,一般都是中文乱码的. 这时的工程就是一个JSP页面的事情,可以添加如下代码 <%@ page language="java" import= ...

  6. eclipse开发servlet应用,Tomcat无法访问jpg图片 ===第二版===

    之前版本中,设置完后,确实可以访问图片了,但是问题接着来了,那就是,无法访问servlet的服务了. 后来想了下,原因也挺好理解的,设置到了Tomcat目录,而项目没有部署,所以没能访问. 但是怎么两 ...

  7. GridView布局及适配器优化

    1.布局样式 <GridView android:id="@+id/gridView" android:layout_width="fill_parent" ...

  8. KMP算法总结

    kmp算法的T子字符串的下标的变化规律 大话数据结构这边书中的KMP算法的讲解跟最终的算法代码还是有很大的差别 java语言只会if判断语句,循环语句,但是这些语句以及可以包罗万象了,可以适用很多情况 ...

  9. 关于java中Double类型的运算精度问题(转)

    Java Java double:浮点数:精确计算  public class Test{    public static void main(String args[]){        Syst ...

  10. ajax省市线三级联动

    <script type='text/javascript' src='http://ajax.useso.com/ajax/libs/jquery/1.7.2/jquery.min.js?ve ...