Compression and Input Splits
 
当我们使用压缩数据作为MapReduce的输入时,需要确认数据的压缩格式是否支持切片?
 
假设HDFS中有一个未经压缩的大小为1GB的文本文件,如果HDFS Block大小为128MB,那么这个文件会被HDFS存储为8个Block。当MapReduce Job使用这个文件作为输入时将会创建8个切片(默认每一个Block生成一个切片),每一个切片关联的数据都可以被一个Map Task独立地处理。
 
如果这个文本文件使用Gzip格式压缩,大小仍为1GB,如前所述,它也会被HDFS存储为8个Block。可是当MapReduce Job使用这个文件作为输入时,为每一个Block生成一个切片是不可行的,取而代之的是整个文件将作为一个切片被一个Map Task所处理。
 
Gzip使用DEFLATE存储压缩数据,DEFLATE将数据存储为一系列的压缩数据块,可是这些压缩数据块的边界是无法区分的,导致在数据流中无法定位某个数据块的起始位置。也就是说,我们无法随意地指定一个位置(该位置不一定恰好是某数据块的起始位置),然后移动到下一个数据块的起始位置读取数据。基本这个原因,Gzip格式的文件是不支持切片的。
 
对于这种情况,MapReduce是可以作出正确处理的,通过文件后缀名(文件后缀名直接影响压缩数据格式的判断)可以判断出这个文件是以Gzip格式进行压缩的,不支持切片,会将整个文件作为一个切片进行处理。但这样做是有很大代价的,一个Map Task要处理整个文件的数据,而且大部分数据并不是“数据本地性”的。
 
如果这个文本文件使用LZO格式压缩,同样的问题也会存在,但是Hadoop LZO Library提供了一个用于预处理LZO文件的切片索引工具,可以简单地认为生成的索引文件中保存着各个切片的起始位置,再配合合适的InputFormat(如:LzoTextInputFormat),运行MapReduce Job时就可以支持切片。
 
Bzip2的各个数据块之间存放有专门的“Synchronization Marker”,因此它是可以支持切片的。
 
Hadoop通常处理的都是大规模的数据集,因此我们必须尽可能的利用压缩优化性能。具体使用哪一个压缩格式依赖于文件大小、文件格式以及我们使用的分析工具。以下是一些使用建议:
 
(1)使用一些容器文件格式,如Sequence File、Avro DataFile、ORCFile、Parquet File,这些文件格式全部支持压缩和切片,配合一个快速的压缩算法(如:LZO、LZ4、Snappy)使用通常是一个好的选择;
 
(2)使用一个支持切片的压缩算法,如bzip2、lzo(通过索引处理之后可以支持切片);
 
(3)将一个文件人为地切分为Chunk(即一个文件被切分为多个文件),然后将这些Chunks逐个的进行压缩,可以使用任意支持的压缩算法,且不需要考虑压缩算法是否支持切片,但是Chunk压缩后的大小需要接近于HDFS Block的大小;
 
(4)文件不作压缩处理。
 
对于大型的文件,我们不能选择不支持切片的压缩算法,因为这会导致MapReduce Job丧失数据本地性且运行效率低下。
 
Using Compression in MapReduce
 
MapReduce读取输入路径中的压缩文件时会自动完成数据解压(可参考CompressionCodecFactory)。
 
如果MapReduce Job的结果输出需要使用压缩,可以通过设置Job的相关配置属性来实现:
 
mapreduce.output.fileoutputformat.compress:true
 
mapreduce.output.fileoutputformat.compress.codec:CompressionCodec全限定类名
 
也可以通过FileOutputFormat提供的静态方法设置,如:
 
FileOutputFormat.setCompressOutput(job, true);
FileOutputFormat.setOutputCompressorClass(job, GzipCodec.class);
 
不同的输出文件格式可能相应的设置属性会有不同。
 
Compressing map output
 
Map Task的输出被写出到本地磁盘,而且需要通过网络传输至Reduce Task的节点,只要简单地使用一个快速的压缩算法(如LZO、LZ4、Snappy)就可以带来性能的提升,因为压缩机制的使用避免了Map Tasks与Reduce Tasks之间大量中间结果数据被传输。可以通过设置相应的Job配置属性开启:
 
mapreduce.map.output.compress:true
 
mapreduce.map.output.compress.codec:CompressionCodec全限定类名
 
也可以通过Configuration API进行设置:
 
new API:
 
Configuration conf = new Configuration();
conf.setBoolean(Job.MAP_OUTPUT_COMPRESS, true);
conf.setClass(Job.MAP_OUTPUT_COMPRESS_CODEC, GzipCodec.class, CompressionCodec.class);
Job job = new Job(conf);
 
old API:
 
conf.setCompressMapOutput(true);
conf.setMapOutputCompressorClass(GzipCodec.class);
 
 
 
 
 
 
 
 

Hadoop MapReduce中压缩技术的使用的更多相关文章

  1. MapReduce 示例:减少 Hadoop MapReduce 中的侧连接

    摘要:在排序和reducer 阶段,reduce 侧连接过程会产生巨大的网络I/O 流量,在这个阶段,相同键的值被聚集在一起. 本文分享自华为云社区<MapReduce 示例:减少 Hadoop ...

  2. hadoop中MapReduce中压缩的使用及4种压缩格式的特征的比较

    在比较四中压缩方法之前,先来点干的,说一下在MapReduce的job中怎么使用压缩. MapReduce的压缩分为map端输出内容的压缩和reduce端输出的压缩,配置很简单,只要在作业的conf中 ...

  3. Hadoop : MapReduce中的Shuffle和Sort分析

    地址 MapReduce 是现今一个非常流行的分布式计算框架,它被设计用于并行计算海量数据.第一个提出该技术框架的是Google 公司,而Google 的灵感则来自于函数式编程语言,如LISP,Sch ...

  4. Hadoop Mapreduce中shuffle 详解

    MapReduce 里面的shuffle:描述者数据从map task 输出到reduce task 输入的这段过程 Shuffle 过程: 首先,map 输出的<key,value >  ...

  5. Hadoop Mapreduce 中的Partitioner

    Partitioner的作用的对Mapper产生的中间结果进行分片,以便将同一分组的数据交给同一个Reduce处理,Partitioner直接影响Reduce阶段的负载均衡. MapReduce提供了 ...

  6. Hadoop Mapreduce 中的FileInputFormat类的文件切分算法和host选择算法

    文件切分算法 文件切分算法主要用于确定InputSplit的个数以及每个InputSplit对应的数据段. FileInputFormat以文件为单位切分成InputSplit.对于每个文件,由以下三 ...

  7. Hadoop Mapreduce中wordcount 过程解析

    将文件split 文件1:                                                                   分割结果: hello  world   ...

  8. 下一代Apache Hadoop MapReduce框架的架构

    背景 随着集群规模和负载增加,MapReduce JobTracker在内存消耗,线程模型和扩展性/可靠性/性能方面暴露出了缺点,为此需要对它进行大整修. 需求 当我们对Hadoop MapReduc ...

  9. Hadoop压缩之MapReduce中使用压缩

    1.压缩和输入分片 Hadoop中文件是以块的形式存储在各个DataNode节点中,假如有一个文件A要做为输入数据,给MapReduce处理,系统要做的,首先从NameNode中找到文件A存储在哪些D ...

随机推荐

  1. Ubuntu 下 JDK+Tomcat+MySql 环境的搭建

    Linux环境 修改catalina.sh 在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行: JAVA_OPTS=&quo ...

  2. 在Quick-cocos2dx中使用云风pbc解析Protocol Buffers,支持win、mac、ios、android

    本例主要介绍 如何将 pbc 集成到quick-cocos2dx框架中,让我们的cocos2dx客户端Lua拥有编解码Protocol Buffers能力. 参考: 云风pbc的用法: http:// ...

  3. Linux - 标准输入转换为标准输出 代码(C)

    标准输入转换为标准输出 代码(C) 本文地址:http://blog.csdn.net/caroline_wendy Linux能够使用getc()和putc(),读取和写入每个输入字符. 代码: / ...

  4. 在Qt中使用sleep

      关于sleep函数,我们先来看一下他的作用:sleep函数是使调用sleep函数的线程休眠,线程主动放弃时间片.当经过指定的时间间隔后,再启动线程,继续执行代码.sleep函数并不能起到定时的作用 ...

  5. mac缺少预编译.a问题

    在win7的svn提交了coco2d-x 3.0代码,在mac进行更新,用xcode打开工程,编译不成功,一看好多的.a文件全部都是红色的,无法找到文件,一开始不了解coco2d-x的prebuilt ...

  6. (转) Unity3D中角色的动画脚本的编写(三)

    在上一篇,我们具体的讲解了有关动画的融合,也提到了有关动画状态的权重问题.那么这次,我来以一个例子的形式来向大家讲解动画的叠加,或许会涉及到多方面的知识,我力求一次讲清.好了,我们开始吧! 首先我们必 ...

  7. 在VisualStudio 2012中通过SmallSharp压缩js及修改web.config

    在项目中加入一个targets文件,取名my.build.targets 在targets文件中加入内容: <?xml version="1.0" encoding=&quo ...

  8. Dagger2学习之由浅入深

    概述 Dagger2是一款使用在Java和Android上的静态的,运行时依赖注入框架.官方地址:http://google.github.io/dagger/ 记得当初刚学习Dagger2的时候看了 ...

  9. call()与apply()区别

    一.方法的定义 call方法: 语法:call(thisObj,Object)定义:调用一个对象的一个方法,以另一个对象替换当前对象.说明:call 方法可以用来代替另一个对象调用一个方法.call ...

  10. jsp页面可以巧用模态框

    jsp页面使用模态框配合ajax出来的效果真的没话说,当然你也可以使用模态框配合action,但是在删除和更新的时候传值有点麻烦,用ajax 就没有这些问题 ,比如删除代码的时候在js文件中传值可以这 ...