hadoop压缩与解压

来源:互联网 发布:淘宝小号安全交易网 编辑:程序博客网 时间:2024/06/05 21:02

一般来说,计算机处理的数据都存在一些冗余度,同时数据中间,尤其是相邻数据存在着相关性,所以可以通过一些有别于原始便拿的特殊编码方式来保存数据,使数据占用的存储空间比较小,这个过程一般叫压缩,和压缩对应的概念是解压缩,就是将被压缩的数据从特殊编码方式还原为原始数据的过程,

压缩广泛应用于海量数据处理中,对原始文件进行压缩,可以有效的减少存储文件所需的空间,并加快数据在网络上或者磁盘上的传输速度,在hadoop中,压缩应用于文件存储,map阶段到reduce 阶段的数据交换等情景。
数据压缩的方式非常多,不同特点的数据有不用的数据压缩方式:如对声音和图像等特殊数据的压缩,就可以采用有损的压缩方法,允许压缩过程中损失一定的信息,换取比较大的压缩比,而对音乐数据的压缩,由于数据有自己比较特殊的编码方式,因此也可以采用一些针对这些特殊编码的专用数据压缩算法、
2.hadoop压缩 简介
hadoop座椅一个叫通用的海量数据处理平台,在使用压缩方式方面,主要考虑压缩速度和压缩文件的可分割性。
所有的压缩算法都会考虑时间和空间的权衡,跟快的压缩和解压缩速度通常会耗费更多的空间,例如,通过gzip命令压缩数据时,用户可以设置不用的选项来选择数据优先或空间优先,选项-1表示优先考虑速度,可以获得最大的压缩比,需要 注意的是,有些压缩算法的压缩和解压缩速度回有比较大的差别:gzip和zip通用的压缩工具,在时间或空间上相对平衡,gzip2压缩比gzip和zip更有效,但是速度比较慢,而且bzip2的压缩速度快于他的压缩速度。
当使用mapreduce处理压缩文件时,需要考虑压缩文件的可分割性,考虑我们需要 保持在hdfs的一个大小为1GB的文件进行处理,当前hdfs的数据块大小为64M的情况下,该文件 被存储为16块,对应的mapreduce作业将会将该文件分为16个输入分片,提供给16个独立的map任务进行处理,但如果该文件时一个gzip格式的压缩文件,这时,mapreduce作业不能将该文件分为16个分片,因为不可能从gzip数据流中的某个点开始,进行数据解压,但是,如果该文件是一个bzip2格式的压缩文件,那么mapreduce作业可以通过bzip2格式压缩文件的快,将 数据划分为若干个输入分片,并从块开始压缩数据,bzip2格式压缩文件中,块与块见提供一个48位的同步标记,因此,bzip2支持数据分割。
hadoop支持的压缩格式:
压缩格式 UNIX工具 算法 文件扩展名 支持多文件 可分割
DEFLATE 无 DEFLATE .deflate 否 否
gzip gzip DEFLATE .gz 否 否
zip zip DEFLATE .zip 是 是
bzip bzip2 bzip2 .bz2 否 是
LZO lzop LZO .lzo 否 否
压缩算法 原始文件大小 压缩后的文件大小 压缩速度 解压缩速度
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
这里写图片描述

(http://my.oschina.net/mkh/blog/335297)


压缩格式



import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.URI;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FSDataInputStream;import org.apache.hadoop.fs.FSDataOutputStream;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 org.apache.hadoop.io.compress.CompressionInputStream;import org.apache.hadoop.io.compress.CompressionOutputStream;import org.apache.hadoop.util.ReflectionUtils;public class CodecTest {    public static void main(String[] args) throws Exception {        compress("org.apache.hadoop.io.compress.BZip2Codec");//        compress("org.apache.hadoop.io.compress.GzipCodec");//        compress("org.apache.hadoop.io.compress.Lz4Codec");//        compress("org.apache.hadoop.io.compress.SnappyCodec");        // uncompress("text");        // uncompress1("hdfs://master:9000/user/hadoop/text.gz");    }    // 压缩文件    public static void compress(String codecClassName) throws Exception {        Class<?> codecClass = Class.forName(codecClassName);        Configuration conf = new Configuration();        FileSystem fs = FileSystem.get(conf);        CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(codecClass, conf);        //输入和输出均为hdfs路径        FSDataInputStream in = fs.open(new Path("/test.log"));        FSDataOutputStream outputStream = fs.create(new Path("/test1.bz2"));        System.out.println("compress start !");        // 创建压缩输出流        CompressionOutputStream out = codec.createOutputStream(outputStream);        IOUtils.copyBytes(in, out, conf);        IOUtils.closeStream(in);        IOUtils.closeStream(out);        System.out.println("compress ok !");    }    // 解压缩    public static void uncompress(String fileName) throws Exception {        Class<?> codecClass = Class                .forName("org.apache.hadoop.io.compress.GzipCodec");        Configuration conf = new Configuration();        FileSystem fs = FileSystem.get(conf);        CompressionCodec codec = (CompressionCodec) ReflectionUtils                .newInstance(codecClass, conf);        FSDataInputStream inputStream = fs                .open(new Path("/user/hadoop/text.gz"));        // 把text文件里到数据解压,然后输出到控制台        InputStream in = codec.createInputStream(inputStream);        IOUtils.copyBytes(in, System.out, conf);        IOUtils.closeStream(in);    }    // 使用文件扩展名来推断二来的codec来对文件进行解压缩    public static void uncompress1(String uri) throws IOException {        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.out.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(out);            IOUtils.closeStream(in);        }    }}

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

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

import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.URI;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FSDataInputStream;import org.apache.hadoop.fs.FSDataOutputStream;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 org.apache.hadoop.io.compress.CompressionInputStream;import org.apache.hadoop.io.compress.CompressionOutputStream;import org.apache.hadoop.util.ReflectionUtils;public class CodecTest {    //压缩文件    public static void compress(String codecClassName) throws Exception{        Class<?> codecClass = Class.forName(codecClassName);        Configuration conf = new Configuration();        FileSystem fs = FileSystem.get(conf);        CompressionCodec codec = (CompressionCodec)ReflectionUtils.newInstance(codecClass, conf);        //指定压缩文件路径        FSDataOutputStream outputStream = fs.create(new Path("/user/hadoop/text.gz"));        //指定要被压缩的文件路径        FSDataInputStream in = fs.open(new Path("/user/hadoop/aa.txt"));        //创建压缩输出流        CompressionOutputStream out = codec.createOutputStream(outputStream);          IOUtils.copyBytes(in, out, conf);         IOUtils.closeStream(in);        IOUtils.closeStream(out);    }    //解压缩    public static void uncompress(String fileName) throws Exception{        Class<?> codecClass = Class.forName("org.apache.hadoop.io.compress.GzipCodec");        Configuration conf = new Configuration();        FileSystem fs = FileSystem.get(conf);        CompressionCodec codec = (CompressionCodec)ReflectionUtils.newInstance(codecClass, conf);        FSDataInputStream inputStream = fs.open(new Path("/user/hadoop/text.gz"));         //把text文件里到数据解压,然后输出到控制台          InputStream in = codec.createInputStream(inputStream);          IOUtils.copyBytes(in, System.out, conf);        IOUtils.closeStream(in);    }    //使用文件扩展名来推断二来的codec来对文件进行解压缩    public static void uncompress1(String uri) throws IOException{        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.out.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(out);            IOUtils.closeStream(in);        }    }    public static void main(String[] args) throws Exception {        //compress("org.apache.hadoop.io.compress.GzipCodec");        //uncompress("text");        uncompress1("hdfs://master:9000/user/hadoop/text.gz");    }}
这里写代码片
0 0
原创粉丝点击