HDFS支持数据压缩的几种方法探讨

来源:互联网 发布:进出口报关软件 编辑:程序博客网 时间:2024/06/05 02:11
HDFS支持数据压缩存在以下几种方法:

1、在HDFS之上将数据压缩好后,再存储到HDFS
2、在HDFS内部支持数据压缩,这里又可以分为几种方法:
    2.1、压缩工作在DataNode上完成,这里又分两种方法:
           2.1.1、数据接收完后,再压缩
                     这个方法对HDFS的改动最小,但效果最低,只需要在block文件close后,调用压缩工具,将block文件压缩一下,然后再打开block文件时解压一下即可,几行代码就可以搞定
           2.1.2、边接收数据边压缩,使用第三方提供的压缩库
                     效率和复杂度折中方法,Hook住系统的write和read操作,在数据写入磁盘之前,先压缩一下,但write和read对外的接口行为不变,比如:原始大小为100KB的数据,压缩后大小为10KB,当写入100KB后,仍对调用者返回100KB,而不是10KB
    2.2、压缩工作交给DFSClient做,DataNode只接收和存储
           这个方法效果最高,压缩分散地推给了HDFS客户端,但DataNode需要知道什么时候一个block块接收完成了。

推荐最终实现采用2.2这个方法,该方法需要修改的HDFS代码量也不大,但效果最高。


这里举一个例子:
 先说文件的压缩有两大好处:1、可以减少存储文件所需要的磁盘空间;2、可以加速数据在网络和磁盘上的传输。尤其是在处理大数据时,这两大好处是相当重要的。

  下面是一个使用gzip工具压缩文件的例子。将文件/user/hadoop/aa.txt进行压缩,压缩后为/user/hadoop/text.gz

  1. package com.hdfs;

  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.OutputStream;
  5. import java.net.URI;

  6. import org.apache.hadoop.conf.Configuration;
  7. import org.apache.hadoop.fs.FSDataInputStream;
  8. import org.apache.hadoop.fs.FSDataOutputStream;
  9. import org.apache.hadoop.fs.FileSystem;
  10. import org.apache.hadoop.fs.Path;
  11. import org.apache.hadoop.io.IOUtils;
  12. import org.apache.hadoop.io.compress.CompressionCodec;
  13. import org.apache.hadoop.io.compress.CompressionCodecFactory;
  14. import org.apache.hadoop.io.compress.CompressionInputStream;
  15. import org.apache.hadoop.io.compress.CompressionOutputStream;
  16. import org.apache.hadoop.util.ReflectionUtils;

  17. public class CodecTest {
  18.     //压缩文件
  19.     public static void compress(String codecClassName) throws Exception{
  20.         Class<?> codecClass = Class.forName(codecClassName);
  21.         Configuration conf = new Configuration();
  22.         FileSystem fs = FileSystem.get(conf);
  23.         CompressionCodec codec = (CompressionCodec)ReflectionUtils.newInstance(codecClass, conf);
  24.         //指定压缩文件路径
  25.         FSDataOutputStream outputStream = fs.create(new Path("/user/hadoop/text.gz"));
  26.         //指定要被压缩的文件路径
  27.         FSDataInputStream in = fs.open(new Path("/user/hadoop/aa.txt"));
  28.         //创建压缩输出流
  29.         CompressionOutputStream out = codec.createOutputStream(outputStream);  
  30.         IOUtils.copyBytes(in, out, conf);
  31.         IOUtils.closeStream(in);
  32.         IOUtils.closeStream(out);
  33.     }
  34.    
  35.     //解压缩
  36.     public static void uncompress(String fileName) throws Exception{
  37.         Class<?> codecClass = Class.forName("org.apache.hadoop.io.compress.GzipCodec");
  38.         Configuration conf = new Configuration();
  39.         FileSystem fs = FileSystem.get(conf);
  40.         CompressionCodec codec = (CompressionCodec)ReflectionUtils.newInstance(codecClass, conf);
  41.         FSDataInputStream inputStream = fs.open(new Path("/user/hadoop/text.gz"));
  42.          //把text文件里到数据解压,然后输出到控制台  
  43.         InputStream in = codec.createInputStream(inputStream);  
  44.         IOUtils.copyBytes(in, System.out, conf);
  45.         IOUtils.closeStream(in);
  46.     }
  47.    
  48.     //使用文件扩展名来推断二来的codec来对文件进行解压缩
  49.     public static void uncompress1(String uri) throws IOException{
  50.         Configuration conf = new Configuration();
  51.         FileSystem fs = FileSystem.get(URI.create(uri), conf);
  52.         
  53.         Path inputPath = new Path(uri);
  54.         CompressionCodecFactory factory = new CompressionCodecFactory(conf);
  55.         CompressionCodec codec = factory.getCodec(inputPath);
  56.         if(codec == null){
  57.             System.out.println("no codec found for " + uri);
  58.             System.exit(1);
  59.         }
  60.         String outputUri = CompressionCodecFactory.removeSuffix(uri, codec.getDefaultExtension());
  61.         InputStream in = null;
  62.         OutputStream out = null;
  63.         try {
  64.             in = codec.createInputStream(fs.open(inputPath));
  65.             out = fs.create(new Path(outputUri));
  66.             IOUtils.copyBytes(in, out, conf);
  67.         } finally{
  68.             IOUtils.closeStream(out);
  69.             IOUtils.closeStream(in);
  70.         }
  71.     }
  72.    
  73.     public static void main(String[] args) throws Exception {
  74.         //compress("org.apache.hadoop.io.compress.GzipCodec");
  75.         //uncompress("text");
  76.         uncompress1("hdfs://master:9000/user/hadoop/text.gz");
  77.     }

  78. }
复制代码
首先执行77行进行压缩,压缩后执行第78行进行解压缩,这里解压到标准输出,所以执行78行会再控制台看到文件/user/hadoop/aa.txt的内容。如果执行79行的话会将文件解压到/user/hadoop/text,他是根据/user/hadoop/text.gz的扩展名判断使用哪个解压工具进行解压的。解压后的路径就是去掉扩展名。

  进行文件压缩后,在执行命令./hadoop fs -ls /user/hadoop/查看文件信息,如下:
  1. [hadoop@master bin]$ ./hadoop fs -ls /user/hadoop/
  2. Found 7 items
  3. -rw-r--r--   3 hadoop supergroup   76805248 2013-06-17 23:55 /user/hadoop/aa.mp4
  4. -rw-r--r--   3 hadoop supergroup        520 2013-06-17 22:29 /user/hadoop/aa.txt
  5. drwxr-xr-x   - hadoop supergroup          0 2013-06-16 17:19 /user/hadoop/input
  6. drwxr-xr-x   - hadoop supergroup          0 2013-06-16 19:32 /user/hadoop/output
  7. drwxr-xr-x   - hadoop supergroup          0 2013-06-18 17:08 /user/hadoop/test
  8. drwxr-xr-x   - hadoop supergroup          0 2013-06-18 19:45 /user/hadoop/test1
  9. -rw-r--r--   3 hadoop supergroup         46 2013-06-19 20:09 /user/hadoop/text.gz

0 0
原创粉丝点击