Hadoop编码解码【压缩解压缩】机制详解(1)
数据压缩的方式非常多,不同特点的数据有不同的数据压缩方式:如对声音和图像等特殊数据的压缩,就可以采用有损的压缩方法,允许压缩过程中损失一定的信 息,换取比较大的压缩比;而对音乐数据的压缩,由于数据有自己比较特殊的编码方式,因此也可以采用一些针对这些特殊编码的专用数据压缩算法。
hadoop使用的压缩工具主要有:
压缩格式 | 工具 | 算法 | 扩展名 | 多文件 | 可分割性 |
---|---|---|---|---|---|
DEFLATE | 无 | DEFLATE | .deflate | 不 | 不 |
GZIP | gzip | DEFLATE | .gzp | 不 | 不 |
ZIP | zip | DEFLATE | .zip | 是 | 是,在文件范围内 |
BZIP2 | bzip2 | BZIP2 | .bz2 | 不 | 是 |
LZO | lzop | LZO | .lzo | 不 | 是 |
压缩算法 | 原始文件大小 | 压缩文件大小 | 压缩速度 | 解压速度 |
---|---|---|---|---|
gzip |
8.3GB |
1.8GB |
17.5MB/s |
58MB/s |
bzip2 |
8.3GB |
1.1GB |
2.4MB/s |
9.5MB/s |
LZO-bset |
8.3GB |
2GB |
4MB/s |
60.6MB/s |
LZO |
8.3GB |
2.9GB |
49.3MB/s |
74.6MB/s |
这还不是全部,hadoop通过压缩流,也就是将文件写进压缩流里面进行数据读写,性能如何呢?
读取未压缩的数据。CompressionOutputStream和CompressionInputStream类似干 java.util.zip.DeflaterOutputStream和java.util.zip.DeflaterInputStream,前两者 还可以提供重置其底层压缩和解压缩功能,当把数据流中的section压缩为单独的块时,这比较重要。比如SequenceFile。
下例中说明了如何使用API来压缩从标谁输入读取的数据及如何将它写到标准输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class StreamCompressor { public static void main(String[] args) throws Exception { String codecClassname = args[0]; Class<?> codecClass = Class.forName(codecClassname); // 通过名称找对应的编码/解码器 Configuration conf = new Configuration(); CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf); // 通过编码/解码器创建对应的输出流 CompressionOutputStream out = codec.createOutputStream(System.out); // 压缩 IOUtils.copyBytes(System. in , out, 4096, false ); out.finish(); } } |
在阅读一个压缩文件时,我们通常可以从其扩展名来推断出它的编码/解码器。以.gz结尾的文件可以用GzipCodec来阅读,如此类推。每个压缩格式的扩展名如第一个表格;
CompressionCodecFactory提供了getCodec()方法,从而将文件扩展名映射到相应的CompressionCodec。此方法接受一个Path对象。下面的例子显示了一个应用程序,此程序便使用这个功能来解压缩文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class FileDecompressor { public static void main(String[] args) throws Exception { String uri = args[0]; Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), conf); Path inputPath = new Path(uri); CompressionCodecFactory factory = new CompressionCodecFactory(conf); CompressionCodec codec = factory.getCodec(inputPath); if (codec == null ) { System.err.println( "No codec found for " + uri); System.exit(1); } String outputUri = CompressionCodecFactory.removeSuffix(uri, codec.getDefaultExtension()); InputStream in = null ; OutputStream out = null ; try { in = codec.createInputStream(fs.open(inputPath)); out = fs.create( new Path(outputUri)); IOUtils.copyBytes( in , out, conf); } finally { IOUtils.closeStream( in ); IOUtils.closeStream(out); } } } |
% hadoop FileDecompressor
file
.gz
CompressionCodecFactory 从io.compression.codecs配置属性定义的列表中找到编码/解码器。默认情况下,这个列表列出了Hadoop提供的所有编码/解码器 (见表4-3),如果你有一个希望要注册的编码/解码器(如外部托管的LZO编码/解码器)你可以改变这个列表。每个编码/解码器知道它的默认文件扩展
名,从而使CompressionCodecFactory可以通过搜索这个列表来找到一个给定的扩展名相匹配的编码/解码器(如果有的话)。
属性名 | 类型 | 默认值 | 描述 |
io.compression.codecs | 逗号分隔的类名 | org.apache.hadoop.io.compress.DefaultCodec, org.apache.hadoop.io.compress.GzipCodec, org.apache.hadoop.io.compress.Bzip2Codec |
用于压缩/解压的CompressionCodec列表 |
考虑到性能,最好使用一个本地库(native library)来压缩和解压。例如,在一个测试中,使用本地gzip压缩库减少了解压时间50%,压缩时间大约减少了10%(与内置的Java实现相比 较)。表4-4展示了Java和本地提供的每个压缩格式的实现。井不是所有的格式都有本地实现(例如bzip2压缩),而另一些则仅有本地实现(例如 LZO)。
压缩格式 | Java实现 | 本地实现 |
DEFLATE | 是 | 是 |
gzip | 是 | 是 |
bzip2 | 是 | 否 |
LZO | 否 | 是 |
Hadoop带有预置的32位和64位Linux的本地压缩库,位于库/本地目录。对于其他平台,需要自己编译库,具体请参见Hadoop的维基百科http://wiki.apache.org/hadoop/NativeHadoop。
本地库通过Java系统属性java.library.path来使用。Hadoop的脚本在bin目录中已经设置好这个属性,但如果不使用该脚本,则需要在应用中设置属性。
默认情况下,Hadoop会在它运行的平台上查找本地库,如果发现就自动加载。这意味着不必更改任何配置设置就可以使用本地库。在某些情况下,可能 希望禁用本地库,比如在调试压缩相关问题的时候。为此,将属性hadoop.native.lib设置为false,即可确保内置的Java等同内置实现 被使用(如果它们可用的话)。
CodecPool(压缩解码池)
如果要用本地库在应用中大量执行压缩解压任务,可以考虑使用CodecPool,从而重用压缩程序和解压缩程序,节约创建这些对象的开销。
下例所用的API只创建了一个很简单的压缩程序,因此不必使用这个池。此应用程序使用一个压缩池程序来压缩从标准输入读入然后将其写入标准愉出的数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class PooledStreamCompressor { public static void main(String[] args) throws Exception { String codecClassname = args[0]; Class<?> codecClass = Class.forName(codecClassname); Configuration conf = new Configuration(); CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf); Compressor compressor = null ; try { compressor = CodecPool.getCompressor(codec);//从缓冲池中为指定的CompressionCodec检索到一个Compressor实例 CompressionOutputStream out = codec.createOutputStream(System.out, compressor); IOUtils.copyBytes(System. in , out, 4096, false ); out.finish(); } finally { CodecPool.returnCompressor(compressor); } } } |
将数据作为一系列压缩过的块进行存储。问题是,每块的开始没有指定用户在数据流中任意点定位到下一个块的起始位置,而是其自身与数据流同步。因此,gzip不支持分割(块)机制。在这种情况下,MapReduce不分割gzip格式的文件,因为它知道输入的是gzip格式(通过文件扩展名得知),而gzip压缩机制不支持分割机制。这样是以牺牲本地化为代价:一个map任务将处理16个HDFS块,大都不是map的本地数据。与此同时,因为map任务少,所以作业分割的粒度不够细,从而导致运行时间变长。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class MaxTemperatureWithCompression { public static void main(String[] args) throws Exception { if (args.length != 2 ) { System.err.println( "Usage: MaxTemperatureWithCompression <input path> " + "<output path>" ); System.exit(- 1 ); } Job job = new Job(); job.setJarByClass(MaxTemperature. class ); FileInputFormat.addInputPath(job, new Path(args[ 0 ])); FileOutputFormat.setOutputPath(job, new Path(args[ 1 ])); job.setOutputKeyClass(Text. class ); job.setOutputValueClass(IntWritable. class ); FileOutputFormat.setCompressOutput(job, true ); FileOutputFormat.setOutputCompressorClass(job, GzipCodec. class ); job.setMapperClass(MaxTemperatureMapper. class ); job.setCombinerClass(MaxTemperatureReducer. class ); job.setReducerClass(MaxTemperatureReducer. class ); System.exit(job.waitForCompletion( true ) ? 0 : 1 ); } } |
1
2
3
4
5
|
Configuration conf = new Configuration(); conf.setBoolean( "mapred.compress.map.output" , true ); conf.setClass( "mapred.map.output.compression.codec" , GzipCodec. class , CompressionCodec. class ); Job job = new Job(conf); |
旧的API要这样配置
1
2
|
conf.setCompressMapOutput( true ); conf.setMapOutputCompressorClass(GzipCodec. class ); |
压缩就到此为止了。总之编码和解码在hadoop有着关键的作用。
Hadoop编码解码【压缩解压缩】机制详解(1)的更多相关文章
- Linux/centos/redhat下各种压缩解压缩方式详解
1.zip命令 zip -r myfile.zip ./* 将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件. 2.unzip unzip -o -d ...
- Hadoop框架:DataNode工作机制详解
本文源码:GitHub·点这里 || GitEE·点这里 一.工作机制 1.基础描述 DataNode上数据块以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是数据块元数据包括长度.校验.时 ...
- Linux下的压缩解压缩命令详解
linux zip命令zip -r myfile.zip ./*将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件. 2.unzipunzip -o - ...
- Linux下的压缩解压缩命令详解及实例
实例:压缩服务器上当前目录的内容为xxx.zip文件 zip -r xxx.zip ./* 解压zip文件到当前目录 unzip filename.zip ====================== ...
- Hadoop框架:NameNode工作机制详解
本文源码:GitHub·点这里 || GitEE·点这里 一.存储机制 1.基础描述 NameNode运行时元数据需要存放在内存中,同时在磁盘中备份元数据的fsImage,当元数据有更新或者添加元数据 ...
- tar压缩解压缩命令详解
tar命令详解 -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用 ...
- linux压缩(解压缩)命令详解
一.tar命令 tar可以为文件和目录创建档案.利用tar,用户可以为某一特定文件创建档案(备份文件),也可以在档案中改变文件,或者向档案中加入新的文件.tar 最初被用来在磁带上创 ...
- Linux下的tar压缩解压缩命令详解
转载自http://www.cnblogs.com/qq78292959/archive/2011/07/06/2099427.html tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压 ...
- Linux下的tar压缩解压缩命令详解(转)
tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...
- Linux下tar压缩解压缩命令详解
tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个.下面的 ...
随机推荐
- android实现log日志输出
1.下载android的log4j的库(的封装) 去: http://code.google.com/p/android-logging-log4j/ 下载对应的 android-logging-lo ...
- 【爬虫】beautiful soup笔记(待填坑)
Beautiful Soup是一个第三方的网页解析的模块.其遵循的接口为Document Tree,将网页解析成为一个树形结构. 其使用步骤如下: 1.创建对象:根据网页的文档字符串 2.搜索节点:名 ...
- MyEclipse Tern was unable to complete your request in time
1.错误描述 2.错误原因 由错误提示可知,是由于MyEclipse Tern不能及时完成回复 3.解决办法 (1)Window--->Preferences--->MyEclipse-- ...
- => 应用在js回调函数中
=> 可以简化以前的回调函数的调用,具体来说: 今后,几乎所有的回调函数都可用箭头函数简化 比如: 1. 所有回调函数都可: 去function改=> 2. 如果函数体只有一句话: 可省略 ...
- Python之numpy库
NumPy库知识结构 更多详细内容参考:http://www.cnblogs.com/zhanglin-0/p/8504635.html
- bzoj 2657 旅游
Written with StackEdit. Description 到了难得的暑假,为了庆祝小白在数学考试中取得的优异成绩,小蓝决定带小白出去旅游~~ 经过一番抉择,两人决定将\(T\)国作为他们 ...
- 5,基于关系和超链接的 API
Tutorial 5: Relationships & Hyperlinked APIs At the moment relationships within our API are repr ...
- WCF Restful 服务 Get/Post请求
Restful Get方式请求: Restful服务 Get请求方式:http://localhost:10718/Service1.svc/Get/A/B/C http://localhost:1 ...
- c++ 遍历任务栏窗口
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h& ...
- WPF简单模拟QQ登录背景动画(转)
介绍 之所以说是简单模拟,是因为我不知道QQ登录背景动画是怎么实现的.这里是通过一些办法把它简化了,做成了类似的效果 效果图 大体思路 首先把背景看成是一个4行8列的点的阵距,X轴Y轴都是距离70.把 ...