Hadoop编码解码【压缩解压缩】机制具体解释(1)
你是选择源文件存储呢?还是处理压缩再存储?非常显然,压缩编码处理是必须的。一段刚刚捕获的60分钟原始视屏可能达到2G,经过压缩处理能够减至500MB左右。一张单反照片可能有5MB。经过压缩之后仅仅有400KB,而质量不会发生明显的损失。
在Hadoop中。压缩应用于文件存储、Map阶段到Reduce阶段的数据交换(须要打开相关的选项)等情景。
数据压缩的方式许多。不同特点的数据有不同的数据压缩方式:如对声音和图像等特殊数据的压缩,就能够採用有损的压缩方法,同意压缩过程中损失一定的信 息,换取比較大的压缩比。而对音乐数据的压缩,因为数据有自己比較特殊的编码方式,因此也能够採用一些针对这些特殊编码的专用数据压缩算法。
hadoop使用的压缩工具主要有:
压缩格式 | 工具 | 算法 | 扩展名 | 多文件 | 可切割性 |
---|---|---|---|---|---|
DEFLATE | 无 | DEFLATE | .deflate | 不 | 不 |
GZIP | gzip | DEFLATE | .gzp | 不 | 不 |
ZIP | zip | DEFLATE | .zip | 是 | 是,在文件范围内 |
BZIP2 | bzip2 | BZIP2 | .bz2 | 不 | 是 |
LZO | lzop | LZO | .lzo | 不 | 是 |
另外还要考虑的就是可不可以切割文件。在hadoop中不可以切割文件是个不好的消息。
由于hadoop处理数据进行计算的时候,须要将大量的大文件拆分,切割就非常重要了。
压缩算法 | 原始文件大小 | 压缩文件大小 | 压缩速度 | 解压速度 |
---|---|---|---|---|
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通过压缩流,也就是将文件写进压缩流里面进行数据读写,性能怎样呢?
要想对正在被写入一个输出流的数据进行压缩。我们能够使用 createOutputStream(OutputStreamout)方法创建一个CompressionOutputStream(未压缩的数据将 被写到此),将其以压缩格式写入底层的流。相反。要想对从输入流读取而来的数据进行解压缩,则调用 createInputStream(InputStreamin)函数,从而获得一个CompressionInputStream,。从而从底层的流
读取未压缩的数据。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仅仅创建了一个非常easy的压缩程序。因此不必使用这个池。此应用程序使用一个压缩池程序来压缩从标准输入读入然后将其写入标准愉出的数据:
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<?
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任务少,所以作业切割的粒度不够细,从而导致执行时间变长。
可是,bzip2格式的压缩文件确实提供了块与块之间的同步标记(一个48位的π近似值) 因此它支持切割机制。
对于文件的收集。这些问题会稍有不同。ZIP是存档格式,因此t能够将多个文件合并为一个ZIP文件。每一个文单独压缩。全部文档的存储位置存储在ZIP文件的尾部。这个属性表明Z l P 文件支持文件边界处切割,每一个分片中包含ZIP压缩文件中的一个或多个文件。
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)的更多相关文章
- Hadoop编码解码【压缩解压缩】机制详解(1)
想想一下,当你需要处理500TB的数据的时候,你最先要做的是存储下来.你是选择源文件存储呢?还是处理压缩再存储?很显然,压缩编码处理是必须的.一段刚刚捕获的60分钟原始视屏可能达到2G,经过压缩处理可 ...
- Huffman编码实现压缩解压缩
这是我们的课程中布置的作业.找一些资料将作业完毕,顺便将其写到博客,以后看起来也方便. 原理介绍 什么是Huffman压缩 Huffman( 哈夫曼 ) 算法在上世纪五十年代初提出来了,它是一种无损压 ...
- Linux,unix,cygwin,centeros下的tar压缩解压缩命令具体解释
tar Examples: tar -cf archive.tar foo bar # Create archive.tar from files foo and bar. tar -tvf ...
- Python3编码解码url
python2和python3对于url的解码和编码 某天做爬虫时遇到一个post请求的参数是编码过的字符串如下,看不懂,初步判断可能是url编码 str = "%7B%22Shopping ...
- Hadoop案例(二)压缩解压缩
压缩/解压缩案例 一. 对数据流的压缩和解压缩 CompressionCodec有两个方法可以用于轻松地压缩或解压缩数据.要想对正在被写入一个输出流的数据进行压缩,我们可以使用createOutput ...
- Delphi Base64编码/解码及ZLib压缩/解压
最近在写的程序与SOAP相关,所以用到了一些Base64编码/解码及数据压缩/解压方面的知识. 在这里来作一些总结: 一.Base64编码/解码 一般用到的是Delphi自带的单元EncdDe ...
- hadoop的压缩解压缩,reduce端join,map端join
hadoop的压缩解压缩 hadoop对于常见的几种压缩算法对于我们的mapreduce都是内置支持,不需要我们关心.经过map之后,数据会产生输出经过shuffle,这个时候的shuffle过程特别 ...
- 【13】MD5编码、Zlib压缩解压缩
1.MD5加密 /// <summary> /// 使用MD5加密算法 /// </summary> /// <param name="md5MessageSt ...
- Hadoop| YARN| 计数器| 压缩| 调优
1. 计数器应用 2. 数据清洗(ETL) 在运行核心业务MapReduce程序之前,往往要先对数据进行清洗,清理掉不符合用户要求的数据.清理的过程往往只需要运行Mapper程序,不需要运行Reduc ...
随机推荐
- 删除VisualStudio 2013中的 "send Feedback" 按钮
在VisualStudio 2013中,在标题栏中增加了一个 "send Feedback" 按钮,用于给微软发送Bug和回馈(或者一个哭脸和笑脸).这个按钮对于开发来说基本上没用 ...
- threadlocal彻底理解
如果你定义了一个单实例的java bean,它有若干属性,但是有一个属性不是线程安全的,比如说HashMap.并且碰巧你并不需要在不同的线程中共享这个属性,也就是说这个属性不存在跨线程的意义.那么你不 ...
- ios unit test 工程选择release时候报错Undefined symbols for architecture i386
Undefined symbols for architecture i386: "_OBJC_CLASS_$_ItemReturn", referenced from: objc ...
- 脑科学对基金经理的八个启示 z
脑科学对基金经理的八个启示 第一,总想要更多.人类大脑是在物资奇缺过程中进化的,所以获得任何“资源”,如食物.性.金钱等,都可以让人感觉良好,大脑也会鼓励我们继续下去. 事实上,可卡因等药物就是“绑架 ...
- 解决https协议服务器内部无法跳转的问题
<!-- 定义视图文件解析{视图解析器} --> <bean class="org.springframework.web.servlet.view.InternalRes ...
- HTML5 Canvas 龟羊赛跑
从一张图上截取不同图块,动态显示在canvas上,形成赛跑的效果.完整代码图片下载请点击 https://files.cnblogs.com/files/xiandedanteng/turtleShe ...
- ssh的一些小操作
不让对方执行w的时候看到我 ssh -T root@8.8.8.8 bin/sh -i 还有一个技巧:远程登录时防止被记录到knowhosts文件(默认为~/.ssh/knowhosts) ssh - ...
- javascript - 封装ajax
封装,使用有示例. // 封装示例: function ajax(url, method, params, done) { var xhr = null; method = method.toUppe ...
- 【转】Intellij IDEA常用配置详解
1. IDEA内存优化 先看看你机器本身的配置而配置. \IntelliJ IDEA 8\bin\idea.exe.vmoptions -------------------------------- ...
- SQL中拆分字符串substr及统计字符出现频数replace用法实例讲解
一.拆分字符串为若干行 例一:要求将表emp中的'king'按照每行一个单词拆成四行 注意:substr(str,pos):截取pos位置开始的字符: substr(str,pos,len):从pos ...