文件压缩主要有两方面的好处:一方面节省文件存储空间;另一方面加速网络数据传输或磁盘读写。当处理大规模的数据时这些效果提升更加明显,因此我们需要仔细斟酌压缩在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. dubbo(soa分布式)与cobar(mysql分布式)

    http://www.jianshu.com/p/0dde591f21d0 (Dubbo编译不是个顺利的事) Cobar是提供关系型数据库(MySQL)分布式服务的中间件,它可以让传统的数据库得到良好 ...

  2. 4道过滤菜鸟的iOS面试题

    网上已经有很多针对各种知识点的面试题,面试时有些人未必真正理解也能通过背题看上去很懂.我自己总结了4道面试题,好快速的判断这个人是否是一个合格的工程师,欢迎大家点评. 1.struct和class的区 ...

  3. yii redirect

    redirect 这个方法是在 CController 里定义的 先来看下官方介绍 redirect() 方法 public void redirect(mixed $url, boolean $te ...

  4. Dedecms调用文章发布时间的方法

    在织梦系统中,有时候需要调用文章发布的时间,格式不同,代码不同.现总结织梦系统dedecms调用文章发布时间的几种方法.   11-20 样式 ([field:pubdate function='st ...

  5. android开发中的5种存储数据方式

    数据存储在开发中是使用最频繁的,根据不同的情况选择不同的存储数据方式对于提高开发效率很有帮助.下面笔者在主要介绍Android平台中实现数据存储的5种方式. 1.使用SharedPreferences ...

  6. 在Global.asax文件里实现通用防SQL注入漏洞程序(适应于post/get请求)

    可使用Global.asax中的Application_BeginRequest(object sender, EventArgs e)事件来实现表单或者URL提交数据的获取,获取后传给SQLInje ...

  7. LINQ to SQL 基础

    取得数据库Gateway 要操作数据库,我们首先要获得一个DataContext对象,这个对象相当于一个数据 库的Gateway,所有的操作都是通过它进行的.这个对象的名字是“Linq to SQL ...

  8. unexpected nil window in _UIApplicationHandleEventFromQueueEvent...

    unexpected nil window in _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow: <UI ...

  9. cas sso单点登录系列6_cas单点登录防止登出退出后刷新后退ticket失效报500错

    转(http://blog.csdn.net/ae6623/article/details/9494601) 问题: 我登录了client2,又登录了client3,现在我把client2退出了,在c ...

  10. hdu1301 Jungle Roads (Prim)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1301 依旧Prim............不多说了 #include<iostream> ...