Hadoop压缩codec

简介

codec其实就是coder和decoder两个单词的词头组成的缩略词。CompressionCodec定义了压缩和解压缩接口,我们这里讲的codec就是实现了CompressionCodec接口的一些压缩格式的类,下面就是这些类的列表:

使用CompressionCodecs解压缩

CompressionCodec有两个方法可以方便的压缩和解压:

压缩:通过createOutputStream(OutputStream out)方法获得CompressionOutputStream对象。

解压:通过createInputStream(InputStream in)方法获得CompressionInputStream对象。

压缩的示例代码

[java] view plain copy

  1. package com.sweetop.styhadoop;
  2. import org.apache.hadoop.conf.Configuration;
  3. import org.apache.hadoop.io.IOUtils;
  4. import org.apache.hadoop.io.compress.CompressionCodec;
  5. import org.apache.hadoop.io.compress.CompressionOutputStream;
  6. import org.apache.hadoop.util.ReflectionUtils;
  7. /**
  8. * Created with IntelliJ IDEA.
  9. * User: lastsweetop
  10. * Date: 13-6-25
  11. * Time: 下午10:09
  12. * To change this template use File | Settings | File Templates.
  13. */
  14. public class StreamCompressor {
  15. public static void main(String[] args) throws Exception {
  16. String codecClassName = args[0];
  17. Class<?> codecClass = Class.forName(codecClassName);
  18. Configuration conf = new Configuration();
  19. CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf);
  20. CompressionOutputStream out = codec.createOutputStream(System.out);
  21. IOUtils.copyBytes(System.in, out, 4096, false);
  22. out.finish();
  23. }
  24. }

从命令行接收一个CompressionCodec实现类的参数,然后通过ReflectionUtils实例化该类,调用CompressionCodec的接口方法对标准输出流进行封装,封装成一个压缩流,通过IOUtils方法把标准输入流拷贝到压缩流中,最后调用CompressionCodec的finish方法,完成压缩。

再来看下命令行:

[html] view plain copy

  1. echo "Hello lastsweetop" | ~/hadoop/bin/hadoop com.sweetop.styhadoop.StreamCompressor  org.apache.hadoop.io.compress.GzipCodec | gunzip -

使用GzipCode类来压缩"Hello lastsweetop",然后再通过gunzip工具解压。

我们来看一下输出:

[html] view plain copy

  1. [exec] 13/06/26 20:01:53 INFO util.NativeCodeLoader: Loaded the native-hadooplibrary
  2. [exec] 13/06/26 20:01:53 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib library
  3. [exec] Hello lastsweetop

使用CompressionCodecFactory解压缩

如果你想读取一个被压缩的文件的话,首先你的先通过扩展名判断该用哪一种codec,当然这里有更简便的方法,CompressionCodecFactory已经帮你把这件事做了,通过传入一个Path调用它的getCodec()方法即可获得相应的codec。我们来看源码:

[java] view plain copy

  1. public class FileDecompressor {
  2. public static void main(String[] args) throws Exception {
  3. String uri = args[0];
  4. Configuration conf = new Configuration();
  5. //获取文件系统
  6. FileSystem fileSystem = FileSystem.get(URI.create(uri), conf);
  7. //构建输入路径
  8. Path inputPath = new Path(uri);
  9. //创建CompressionCodecFactory对象
  10. CompressionCodecFactory factory = new CompressionCodecFactory(conf);
  11. //获取文件的压缩格式
  12. CompressionCodec codec = factory.getCodec(inputPath);
  13. //如果压缩格式不存在就退出
  14. if (codec == null){
  15. System.out.println("No codec found for " + uri);
  16. System.exit(1);
  17. }
  18. //去掉文件的后缀,键outputUri作为解压的输出路径
  19. String outputUri = CompressionCodecFactory.removeSuffix(uri, codec.getDefaultExtension());
  20. //定义输入输出流
  21. InputStream in = null;
  22. OutputStream out = null;
  23. try {
  24. //创建输入输出流
  25. in = codec.createInputStream(fileSystem.open(inputPath));
  26. out = fileSystem.create(new Path(outputUri));
  27. //解压
  28. IOUtils.copyBytes(in, out, conf);
  29. } catch (Exception e) {
  30. e.printStackTrace();
  31. }finally{
  32. IOUtils.closeStream(in);
  33. IOUtils.closeStream(out);
  34. }
  35. }
  36. }

注意看下removeSuffix方法,这是一个静态方法,它可以将文件的后缀去掉,然后我们将这个路径作为解压的输出路径。CompressionCodeFactory能找到的codec也是有限的,默认只有三种org.apache.hadoop.io.compress.GzipCodec;org.apache.hadoop.io.compress.BZip2Codec;org.apache.hadoop.io.compress.DefaultCodec。如果想要添加其他的codec你需要更改io.compression.codecs属性,并注册codec。

原生库

现在越来越多原生库的概念,HDFS的codec也不例外,原生库可以极大的提升性能比如gzip的原生库解压提高50%,压缩提高10%,但不是所有codec都有原生库的,而一些codec只有原生库。我们来看下列表:

Linux下,hadoop以前提前编译好了32位的原生库和64位的原生库,我们看下:

[html] view plain copy

  1. [[email protected] native]$pwd
  2. /home/hadoop/hadoop/lib/native
  3. [[email protected] native]$ls -ls
  4. total 8
  5. 4 drwxrwxrwx 2 root root 4096 Nov 14  2012 Linux-amd64-64
  6. 4 drwxrwxrwx 2 root root 4096 Nov 14  2012 Linux-i386-32

如果是其他平台的话,你就需要自己编译了,详细步骤请看这里:http://wiki.apache.org/hadoop/NativeHadoop
java原生库的路径可以通过java.library.path指定,在bin目录下,hadoop的启动脚本已经指定,如果你不用这个脚本,那么你就需要在你的程序中指定了。

[html] view plain copy

  1. if [ -d "${HADOOP_HOME}/build/native" -o -d "${HADOOP_HOME}/lib/native" -o -e "${HADOOP_PREFIX}/lib/libhadoop.a" ]; then
  2. if [ -d "$HADOOP_HOME/build/native" ]; then
  3. JAVA_LIBRARY_PATH=${HADOOP_HOME}/build/native/${JAVA_PLATFORM}/lib
  4. fi
  5. if [ -d "${HADOOP_HOME}/lib/native" ]; then
  6. if [ "x$JAVA_LIBRARY_PATH" != "x" ]; then
  7. JAVA_LIBRARY_PATH=${JAVA_LIBRARY_PATH}:${HADOOP_HOME}/lib/native/${JAVA_PLATFORM}
  8. else
  9. JAVA_LIBRARY_PATH=${HADOOP_HOME}/lib/native/${JAVA_PLATFORM}
  10. fi
  11. fi
  12. if [ -e "${HADOOP_PREFIX}/lib/libhadoop.a" ]; then
  13. JAVA_LIBRARY_PATH=${HADOOP_PREFIX}/lib
  14. fi
  15. fi

hadoop会去查找对应的原生库,并且自动加载,你不需要关心这些设置。但某些时候你不想使用原生库,比如调试一些bug的时候,那么可以通过hadoop.native.lib设置为false来实现。

如果你用原生库做大量的压缩和解压的话可以考虑用CodecPool,有点像连接池,这样你就无需频繁的去创建codec对象。

[java] view plain copy

  1. public class PooledStreamCompressor {
  2. public static void main(String[] args) throws ClassNotFoundException {
  3. String codecClassName = args[0];
  4. //获取压缩类的字节码用于反射
  5. Class<?> codecClass = Class.forName(codecClassName);
  6. //创建配置信息
  7. Configuration conf = new Configuration();
  8. //通过反射机制创建压缩类
  9. CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf);
  10. //定义压缩类
  11. Compressor compressor = null;
  12. try {
  13. //通过CodecPool创建compressor
  14. compressor = CodecPool.getCompressor(codec);
  15. //创建压缩类对象
  16. CompressionOutputStream out = codec.createOutputStream(System.out, compressor);
  17. //压缩
  18. IOUtils.copyBytes(System.in, out,4096, false);
  19. //完成
  20. out.finish();
  21. } catch (Exception e) {
  22. e.printStackTrace();
  23. } finally {
  24. CodecPool.returnCompressor(compressor);
  25. }
  26. }
  27. }

代码比较容易理解,通过CodecPool的getCompressor()方法获得Compressor对象,该方法需要传入一个codec,然后Compressor对象在createOutputStream中使用,使用完毕后再通过returnCompressor()放回去。
输出结果如下:

[html] view plain copy

  1. [exec] 13/06/27 12:00:06 INFO util.NativeCodeLoader: Loaded the native-hadoop library
  2. [exec] 13/06/27 12:00:06 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib library
  3. [exec] 13/06/27 12:00:06 INFO compress.CodecPool: Got brand-new compressor
  4. [exec] Hello lastsweetop

原文来自:http://blog.csdn.net/lastsweetop/article/details/9173061

代码来自:https://github.com/lastsweetop/styhadoop

时间: 2024-10-07 15:13:45

Hadoop压缩codec的相关文章

hadoop压缩框架

一般来说,计算机处理的数据都存在一些冗余度,同时数据中间,尤其是相邻数据间存在着相关性,所以可以通过一些有别于原始编码的特殊编码方式来保存数据,使数据占用的存储空间比较小,这个过程一般叫压缩.和压缩对应的概念是解压缩,就是将被压缩的数据从特殊编码方式还原为原始数据的过程. 压缩广泛应用于海量数据处理中,对数据文件进行压缩,可以有效减少存储文件所需的空间,并加快数据在网络上或者到磁盘上的传输速度.在Hadoop中,压缩应用于文件存储.Map阶段到Reduce阶段的数据交换(需要打开相关的选项)等情

Hadoop压缩之CompressionCodecFactory

1.CompressionCodecFactory简介 当在读取一个压缩文件的时候,可能并不知道压缩文件用的是哪种压缩算法,那么无法完成解压任务.在Hadoop中,CompressionCodecFactory通过使用其getCodec()方法,可以通过文件扩展名映射到一个与其对应的CompressionCodec类,如README.txt.gz通过getCodec()方法后,GipCodec类.关于Hadoop的压缩,可以参考我的博文<Hadoop压缩>http://www.cnblogs.

hadoop压缩与解压

1 压缩 一般来说,计算机处理的数据都存在一些冗余度,同时数据中间,尤其是相邻数据间存在着相关性,所以可以通过一些有别于原始编码的特殊编码方式来保存数据, 使数据占用的存储空间比较小,这个过程一般叫压缩.和压缩对应的概念是解压缩,就是将被压缩的数据从特殊编码方式还原为原始数据的过程. 压缩广泛应用于海量数据处理中,对数据文件进行压缩,可以有效减少存储文件所需的空间,并加快数据在网络上或者到磁盘上的传输速度.在Hadoop中,压缩应用于文件存储.Map阶段到Reduce阶段的数据交换(需要打开相关

Hadoop压缩之MapReduce中使用压缩

1.压缩和输入分片 Hadoop中文件是以块的形式存储在各个DataNode节点中,假如有一个文件A要做为输入数据,给MapReduce处理,系统要做的,首先从NameNode中找到文件A存储在哪些DataNode中,然后,在这些DataNode中,找到相应的数据块,作为一个单独的数据分块,作为map任务的输入,这就是mapreduce处理的数据的粗略过程!但是,我们都知道,对于一些大型的数据,压缩是很有用的,不仅能够节省存储空间,而且还能够加快传输速率.把文件压缩后再存入数据节点中,这个很常见

十七、hadoop压缩相关

一.数据压缩在hadoop中的意义 1.基本概述 ? 压缩技术可以减少底层hdfs的读写字节数.并且能够降低在数据传输过程中占用的网络带宽资源,以及降低占用的磁盘空间.而在MapReduce中,shuffle以及merge过程都面临着巨大的IO压力.但是要注意增加了压缩,另外一方面会增加cpu的负载.所以在要权衡好是否采用压缩,以及采用的压缩算法的特性. 2.压缩应用基本原则 运算密集型的job,少用压缩.因为压缩占用cpu.IO密集型的job,可用压缩减少数据量.选择压缩算法时,要注意压缩比,

Hadoop压缩解压缩

数据从外部进入Map时,可能这个文件是压缩的,对于常见的压缩不用关心,Map内部都是内置支持的. 当Map执行完成,产生输出到Reduce的时,这时候需要经过一个Shuffer过程,需要传输,十分消耗网络资源,那么在这种情况下数据传输量越小越好. 这时候我们可以对Map的输出进行压缩以减少文件的大小,减少传输量. Reduce输出也可以做压缩 说明,可分割性: 如果文件不可分割,意味着整个文件将作为输入源处理.不能分割的话 即使一个T的数据也会将交给一个map处理 如何支持Map段的输出和Red

Hadoop序列化与压缩

传统的的计算机系统通过I/O操作与外界交流,,Hadoop的I/O由传统的I/O系统发展而来,但是又有些不同,Hadoop需要处理P.T级别的数据,所以在org.apache.hadoop.io包中包含了一些面向海量数据处理的基本输入输出工具,本文会对其中的序列化和压缩进行研究. 1 序列化 对象的序列化用于将对象编码成一个字节流,以及从字节流中重新构建对象.将一个对象编码成一个字节流称为序列化对象(Serializing),相反的处理过程称为反序列化. 序列化有三种主要的用途: A.作为一种持

Hadoop之——MapReduce实战(二)

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/45957715 MapReduce的老api写法 import org.apache.hadoop.fs.Path; import org.apache.hadoop.mapred.FileInputFormat; import org.apache.hadoop.mapred.FileOutputFormat; import org.apache.hadoop.mapred.Jo

HADOOP与HDFS数据压缩格式

1.cloudera 数据压缩的一般准则 一般准则 是否压缩数据以及使用何种压缩格式对性能具有重要的影响.在数据压缩上,需要考虑的最重要的两个方面是 MapReduce 作业和存储在 HBase 中的数据.在大多数情况下,每个的原则都类似. 您需要平衡压缩和解压缩数据所需的能力.读写数据所需的磁盘 IO,以及在网络中发送数据所需的网络带宽.正确平衡这些因素有赖于集群和数据的特征,以及您的 使用模式. 如果数据已压缩(例如 JPEG 格式的图像),则不建议进行压缩.事实上,结果文件实际上可能大于原