Hadoop权威指南:压缩

文件压缩的两个好处:

  • 减少储存文件所需要的磁盘空间
  • 加速数据在网络和磁盘上的传输

压缩格式总结:

压缩格式 工具 算法 文件扩展名 是否可切分
DEFLATE DEFLATE .deflate
Gzip gzip DEFLATE .gz
bzip2 bzip2 bzip2 .bz2
LZO lzop LZO .lzo
LZ4 LZ4 .lz4
Snappy Snappy .snapp

上述表中的所有压缩工具都提供9个不同的选项来控制压缩时必须考虑的权衡:

  • -1位优化压缩速度
  • -9为优化压缩空间

codec

codec 实现了一种压缩-解压算法

Hadoop中一个对CompressionCodec接口的实现代表一个codec

Hadoop的压缩codec

压缩格式 HadoopCompressionCodec
DEFLATE org.apache.hadoop.io.compress.DefaultCodec
gzip org.apache.hadoop.io.compress.GzipCodec
bzip2 org.apache.hadoop.io.compress.BZip2Codec
LZO com.hadoop.compression.lzo.LzopCodec
LZ4 org.apache.hadoop.io.compress.Lz4Codec
Snappy org.apache.hadoop.io.compress.SnappyCodec

通过CompressionCodec对数据流进行压缩和解压缩

CompressionCodec包含两个函数 可以轻松用于压缩和解压缩数据

  • createOutputStream(OutputStream out)方法在底层数据流中对需要以压缩格式写入在此之前尚未压缩的数据新建一个CompressionOutputStream对象
  • 对输入数据流中读取的数据进行解压缩的时候,则调用createInputStream(InputStream in)获取CompressionInputStream,通过该方法从底层数据里读取解压缩后的数据

压缩从标准输入读取的数据,并写到标准输出

代码

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.CompressionOutputStream;
import org.apache.hadoop.util.ReflectionUtils; import java.io.IOException; public class StreamCompressor {
public static void main(String args[]) throws ClassNotFoundException, IOException {
// 符合ReflectionUtils的实现
String codecClassname = args[0];
Class<?> codecClass = Class.forName(codecClassname);
Configuration conf = new Configuration();
// 新建codec实例
CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf); // 获得在System.out上支持压缩的一个包裹方法
CompressionOutputStream out = codec.createOutputStream(System.out);
// 对IOUtils对象调用copyBytes()方法将输入数据复制到输出
// 输出由CompressionOutputStream对象压缩
IOUtils.copyBytes(System.in, out, 4096, false);
// 要求压缩方法完成到压缩数据流的写操作
out.finish();
}
} // echo "Test" | hadoop StreamCompressor org.apache.hadoop.io.compress.GzipCodec | gunzip

编译

javac StreamCompressor.java

测试

压缩从标准输入读取的数据,并写到标准输出,通过管道传递给gunzip, 显示压缩内容

echo "Test" | hadoop StreamCompressor org.apache.hadoop.io.compress.GzipCodec | gunzip

通过CompressionCodecFactory推断CompressionCodec

根据文件扩展名选取codec解压缩文件

代码

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.CompressionCodecFactory; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI; public class FileDecompressor {
public static void main(String args[]) throws IOException {
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);
}
}
}
  • 通过使用CompressionCodecFactorygetCodec()方法, 得到相应的CompressionCodec或者nullCompressionCodecFactory可通过搜索注册的codec 找到匹配指定文件扩展名的 codec
  • 如果压缩的是单个文本文件, 可以直接使用cat名查看解压缩后生成的文件

编译

javac FileDecompressor.java

运行

hadoop FileDecompressor /usr/hadoop/file.gz

  • file.gz 要在hdfs中存在
  • 会被解压在hdfs中名为file的文件

压缩代码库的实现

  • 使用原生类库来实现解压缩, 会节约解压缩的时间.
  • 可以通过Java系统的java.library.path属性指定原生代码库
压缩格式 是否有Java实现 是否有原生(native)实现
DEFLATE
gzip
bzip2
LZO
LZ4
Snappy

CodecPool

  • CodecPool对象支持反复使用压缩和解压缩操作, 以减少创建对象的开销

使用压缩池对读取自标准输入的数据进行压缩,然后将其写到标准输出

代码

/*
* Hadoop权威指南:第四章
* */ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.compress.CodecPool;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.CompressionOutputStream;
import org.apache.hadoop.io.compress.Compressor;
import org.apache.hadoop.oncrpc.security.SysSecurityHandler;
import org.apache.hadoop.util.ReflectionUtils; import java.io.IOException; public class PooledStreamCompressor {
public static void main(String args[]) throws ClassNotFoundException, IOException {
String codecClassName = args[0];
// 找到对应CompressionCodec类
Class<?> codeClass = Class.forName(codecClassName);
Configuration conf = new Configuration();
// 通过类名创建实例对象
CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codeClass, conf);
Compressor compressor = null; try {
// 得到compressor
compressor = CodecPool.getCompressor(codec);
CompressionOutputStream out = codec.createOutputStream(System.out, compressor);
IOUtils.copyBytes(System.in, out, 4096, false);
out.flush();
} finally {
// 将compressor返回CodecPool中
CodecPool.returnCompressor(compressor);
}
}
}
  • codec的重载方法createOutputStream中,对于制定的CompressionCodec,我们从池中获取一个Compressor实例

压缩和输入分片

  • 了解这些压缩格式是否支持切分非常重要,例如, 文件压缩为某种个格式后,为1G, 它将被储存成16块(每块是64M的话), 如果该压缩格式不支持切分, 那么就每个块就不能单独作为输入文件,无法实现从压缩数据流任意位置读取数据

应该使用哪种压缩格式?

大致按照效率从高到低排列:

  • 适应容器文件格式,例如顺序文件,REFile或者Avro数据问津, 这些格式同时支持压缩和切分.通常最好与一个快速压缩工具联合使用,例如:LZO,LZ4或者Snappy
  • 使用支持切分的压缩格式, 例如bzip2, 或者使用通过索引实现切分的压缩格式, 例如:LZO
  • 在应用中将文件切分成块,并使用任意一种压缩格式为每个数据块建立压缩文件(不论它是否支持切分).这时, 需要合理选择数据块大小, 以确保压缩后数据块的大小近似于HDFS块的大小
  • 储存未经压缩的文件

对于大文件来说,不要使用不支持切分整个文件的压缩格式,因为会失去数据的本地特性,进而造成MapReduce应用效率低下

在MapReduce中使用压缩

解压缩输入

  • 如果输入文件是压缩的,那么在根据文件扩展名推断出相应的codec后,MapReduce会在读取文件是自动解压缩文件

解压缩输出

  • 要想压缩MapReduce作业的输出,应在作业配置过程中将mapred.output.compress设为truemapred.output.compression.codec属性设置为打算使用的压缩codec的类名
  • 要想压缩MapReduce作业的输出,还可以在FileOutputFormat中使用更便捷的方法设置这些属性

对查找最高温作业所产生输出进行压缩

代码

/*
* Hadoop权威指南:第四章
* */ import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.compress.GzipCodec;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import java.io.IOException; public class MaxTemperatureWithCompression {
public static void main(String args[]) throws IOException, ClassNotFoundException, InterruptedException {
if (args.length != 2) {
System.err.println("Usage: MaxTemperatureWithCompression <input path> <output path>");
System.exit(-1);
} Job job = new Job();
job.setJarByClass(MaxTempreture.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);
}
}

运行

hadoop MaxTemperatureWithCompression input/sample.txt.gz output

最终输出的每个部分都是经过压缩的

查看输出

gunzip -c output/part-c-00000.gz

为输出生成顺序文件(sequence file)

  • 可以设置mapred.output.compression.type属性来控制限制使用压缩格式,默认值为RECORD, 即对每一条记录进行压缩, 如果将其改为BLOCK,将针对一组记录进行压缩
  • SequenceFileOutputFormat类中还有一个静态方法putCompressionType()可用来便捷地设置该属性
MapReduce压缩格式

下表归纳概述了用于设置MapReduce作业输出的压缩格式的配置属性

属性名称 类型 默认值 描述
mapred.output.compress boolean false 压缩输出
mapred.output.compression.codec 类名称 org.apache.hadoop.io.compress.DefaultCodec map输出所用的压缩codec
mapred.output.compression.type String RECORD SqeuenceFile的输出可以使用的压缩类型:NONE,RECORD,BLOCK

对map任务输出进行压缩

map任务的输出需要写到磁盘并通过网络传输到reducer节点,所以如果使用LZO,LZ4或者Snappy这样的快速压缩方式,是可以获取性能提升的

map任务输出的压缩属性

属性名称 类型 默认值 描述
mapred.compress.map.output boolean false 对map任务输出进行压缩
mapred.map.output.compression.codec Class org.apache.hadoop.io.compress.DefaultCodec map输出所有的压缩codec

示例代码

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);

Hadoop权威指南:压缩的更多相关文章

  1. 基于python的《Hadoop权威指南》一书中气象数据下载和map reduce化数据处理及其可视化

    文档内容: 1:下载<hadoop权威指南>中的气象数据 2:对下载的气象数据归档整理并读取数据 3:对气象数据进行map reduce进行处理 关键词:<Hadoop权威指南> ...

  2. 《Hadoop权威指南》读书笔记1

    <Hadoop权威指南>读书笔记 Day1 第一章 1.MapReduce适合一次写入.多次读取数据的应用,关系型数据库则更适合持续更新的数据集. 2.MapReduce是一种线性的可伸缩 ...

  3. Hadoop权威指南(中文版,第2版)【分享】

    下载地址 Hadoop权威指南(中文版,第2版) http://download.csdn.net/download/u011000529/5726789 (友情提示:请点击右下的 “联通下载” 或者 ...

  4. Hadoop权威指南学习笔记二

    MapReduce简单介绍 声明:本文是本人基于Hadoop权威指南学习的一些个人理解和笔记,仅供学习參考,有什么不到之处还望指出,一起学习一起进步. 转载请注明:http://blog.csdn.n ...

  5. Hadoop权威指南:MapReduce应用开发

    Hadoop权威指南:MapReduce应用开发 [TOC] 一般流程 编写map函数和reduce函数 编写驱动程序运行作业 用于配置的API Hadoop中的组件是通过Hadoop自己的配置API ...

  6. Hadoop权威指南:通过FileSystem API读取数据

    Hadoop权威指南:通过FileSystem API读取数据 [TOC] 在Hadoop中,FileSystem是一个通用的文件系统API 获取FileSystem实例的几个静态方法 public ...

  7. Hadoop权威指南:从Hadoop URL读取数据

    [TOC] Hadoop权威指南:从Hadoop URL读取数据 使用java.net.URL对象从Hadoop文件系统读取文件 实现类似linux中cat命令的程序 文件名 HDFSCat.java ...

  8. Hadoop权威指南:数据完整性

    Hadoop权威指南:数据完整性 [TOC] 常用的错误检测码是CRC-32(循环冗余校验) HDFS的数据完整性 HDFS会对写入的所有数据计算校验和,并在读取数据时验证校验和 datanode负责 ...

  9. Hadoop权威指南:HDFS-Hadoop存档

    Hadoop权威指南:HDFS-Hadoop存档 [TOC] 每个文件按块方式存储, 每个块的元数据存储在namenode的内存中 Hadoop存档文件或HAR文件是一个更高效的文件存档工具,它将文件 ...

随机推荐

  1. Java Restful框架:Jersey入门示例(官方例子)

    本文主要介绍了Java Restful框架Jersey入门例子(来源于官方网站https://jersey.java.net/),废话不多说进入正题. 在Jersey官方示例中(https://jer ...

  2. DedeCMS新建模型字段【附件样式】修改方法

    当我们在系统模型中添加了一个自定义附件类型字段的时候,例如我在后台添加一个名为"fujian"的附件类型的字段,字段的实际内容为:'/uploads/soft/2245/1-255 ...

  3. webservice中采用协议Http,它是指什么意思

    webservice 协议 Web Service使用的是 SOAP (Simple Object Access Protocol)协议soap协议只是用来封装消息用的.封装后的消息你可以通过各种已有 ...

  4. MFC中PeekMessage的使用,非阻塞消息循环

    在程序设计的时候经常要进行一个数据循环,比如播放音乐需要循环的向缓冲区里面写入数据,在这个时候比较通用的方法是建立一个线程做事情,但是有时候不想创建多线程就可以使用微软提供的PeekMessage方法 ...

  5. ucgui汉字库存放到外部的flash(控件可用)及写外部FLASH小软件

    源:ucgui汉字库存放到外部的flash(控件可用)及写外部FLASH小软件 如何将ucgui的汉字库存放到外部的flash memory(ucgui)(汉字库)(外部flash) ucgui的字库

  6. 五、pig学习

    一.什么是pig 1.pig和sql.map-reduce的关系 来自为知笔记(Wiz)

  7. CSS3 Media Queries 详解

    说起CSS3的新特性,就不得不提到 Media Queries .最近 Max Design 更新的一个泛读列表里,赫然就有关于 Media Queries 的文章.同时位列其中的也有前天我刚刚翻译的 ...

  8. Web开发中需要了解的东西

    在StackExchange上有人问了这样一个问题:What should every programmer know about web development?(关于Web开发,什么是所有程序员需 ...

  9. POJ 3362 Protecting the Flowers

    这题和金华区域赛A题(HDU 4442)是一样的做法. 对两个奶牛进行分析,选择两个奶牛总花费少的方式排序. bool cmp(const X&a,const X&b){ return ...

  10. STM8的GPIO驱动

    芯片的外设一般按照这么几个流程来进行,GPIO,外部中断,定时器,串口,ADC,IIC,SPI,下面我就按照各个模式来写 首先是GPIO,STM8的GPIO拥有复用功能,这句话告诉我们必然需要配置IO ...