从零开始学习Hadoop--第5章 压缩

原创
2017/01/17 09:13
阅读数 34

1. 压缩从头说

一般来说,数据存在冗余度。数据包括图像文本视频音频。减少数据的冗余度,让数据的体积更小一点,这叫压缩。从压缩后的数据,重新解析出原始数据,叫解压缩。


压缩无处不在。压缩的算法非常多。


Hadoop来说,有两个地方需要用到压缩:其一,在HDFS上存储数据文件,压缩之后数据体积更小,有利存储;其二,集群间的通讯需要压缩数据,这样可以提高网络带宽的利用率。如果用MapReduce处理压缩文件,那么要求压缩算法能支持文件分割,因为MapReduce的过程需要将文件分割成多个切片,如果压缩算法不支持分割,就不能做切片了。

Java里,一切输入输出都用流的方式进行。一个可以读取字节序列的对象叫输入流。文件,网络连接,内存区域,都可以是输入流。一个可以写入字节序列的对象叫输出流。文件,网络连接,内存区域,都可以是输出流。


Hadoop如何压缩?假设,输入流是A,输出流是BAB有很多种可能,可以是文件,网络连接,内存区域,标准输入,标准输出的两两组合。做压缩的话,先选择压缩算法,然后根据压缩算法创建相应的压缩器,然后用压缩器和输出流B创建压缩输出流C,最后,将数据从输入流A复制到压缩输出流C即可进行压缩并输出结果。


如果是解压缩,先选择解压缩算法,然后根据解压缩算法创建相应的解压缩器,然后用解压缩器和输入流A创建压缩输入流C,最后,将数据从输入流C复制到输出流B即可进行解压缩并输出结果。

2.从文件到文件的压缩

2.1 文件和目录结构

这个程序将HDFS上的一个文本文件压缩到另外一个文件。

创建目录~/cprsf2f存放源代码、编译和打包结果。在cprsf2f目录下,有两个子目录,分别是src目录和classes目录,src目录存放Java源代码,class存放编译结果。在src目录下,只有一个源代码文件CprsF2F.java

2.2 CprsF2F.java源文件的代码

packagecom.brianchen.hadoop;


importjava.net.URI;

importjava.io.InputStream;

importjava.io.OutputStream;


importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.io.compress.CompressionCodec;

importorg.apache.hadoop.io.IOUtils;

importorg.apache.hadoop.fs.Path;

importorg.apache.hadoop.fs.FileSystem;

importorg.apache.hadoop.util.ReflectionUtils;


public classCprsF2F{

public staticvoid main(String[] args) throws Exception{

if(args.length != 3){

System.err.println("Usage:CprsF2F cmps_name src target");

System.exit(2);

}


Class<?>codecClass = Class.forName(args[0]);

Configurationconf = new Configuration();

CompressionCodeccodec = (CompressionCodec)ReflectionUtils.newInstance(codecClass,conf);

InputStreamin = null;

OutputStreamout = null;

FileSystem fs= FileSystem.get(URI.create(args[1]), conf);


try{

in =fs.open(new Path(args[1]));

out =codec.createOutputStream(fs.create(new Path(args[2])));

IOUtils.copyBytes(in,out, conf);

}finally{

IOUtils.closeStream(in);

IOUtils.closeStream(out);

}

}

}



2.3 编译

cd~/cprsf2f”

jvac-cp /home/brian/usr/hadoop/hadoop-1.2.1/hadoop-core-1.2.1.jar -d./class/ src/*.java”

2.4 打包

jar-cvf cprsf2f.jar -C ./class/ .”

2.5 执行

cd~/usr/hadoop/hadoop-1.2.1”

echo"hellowrod" >> a.txt”

./bin/hadoopfs -put a.txt a.txt”

./bin/hadoopjar /home/brian/cprsf2f/cprsf2f.jar com.brianchen.hadoop.CprsF2Forg.apache.hadoop.io.compress.GzipCodec a.txt b.txt”

./bin/hadoopfs -cat b.txt”

./bin/hadoopfs -cat b.txt|gunzip”

首先需要确认Hadoop已经启动。用echo命令创建一个内容是”helloworld”的文件a.txt。将a.txt文件复制到HDFS。执行jar,将文件a.txt压缩成b.txt。压缩完毕之后,执行cat,检查b.txt内容,这时候显示的是乱码,因为原始内容已经被压缩了。然后再执行“./bin/hadoopfs -cat b.txt | gunzip”,这次会显示出”helloworld”,因为管道命令gunzip会将压缩文件的内容进行解压缩然后输出。

3.从标准输入到文件的压缩

3.1 文件和目录结构

这个程序从标准输入读取字符串,然后讲它压缩到HDFS的文件存储。创建目录~/cprsin2f存放源代码、编译和打包结果。在cprsin2f目录下,有两个子目录,分别是src目录和classes目录,src目录存放Java源代码,class存放编译结果。在src目录下,只有一个源代码文件CprsIn2F.java

3.2 CprsIn2F.java源文件的代码


packagecom.brianchen.hadoop;


importjava.net.URI;

importjava.io.OutputStream;


importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.io.compress.CompressionCodec;

importorg.apache.hadoop.io.IOUtils;

importorg.apache.hadoop.fs.Path;

importorg.apache.hadoop.fs.FileSystem;

importorg.apache.hadoop.util.ReflectionUtils;


public classCprsIn2F{

public staticvoid main(String[] args) throws Exception{

if(args.length != 2){

System.err.println("Usage:CprsIn2F cmps_name target");

System.exit(2);

}


Class<?>codecClass = Class.forName(args[0]);

Configurationconf = new Configuration();

CompressionCodeccodec = (CompressionCodec)ReflectionUtils.newInstance(codecClass,conf);

OutputStreamout = null;

FileSystem fs= FileSystem.get(URI.create(args[1]), conf);

try{

out =codec.createOutputStream(fs.create(new Path(args[1])));

IOUtils.copyBytes(System.in,out, 4096, false);

}finally{

IOUtils.closeStream(out);

}

}

}


3.3 编译

cd~/cprsin2f”

jvac-cp /home/brian/usr/hadoop/hadoop-1.2.1/hadoop-core-1.2.1.jar -d./class/ src/*.java”

3.4 打包

jar-cvf cprsf2f.jar -C ./class/ .”

3.5 执行

cd~/usr/hadoop/hadoop-1.2.1”

echo“hello, world!” | ./bin/hadoop jar/home/brian/cprsf2f/cprsf2f.jar com.brianchen.hadoop.CprsF2Forg.apache.hadoop.io.compress.GzipCodec hello.txt”

./bin/hadoopfs -cat hello.txt”

./bin/hadoopfs -cat hello.txt|gunzip”

首先需要确认Hadoop已经启动。注意,第二行的命令的双引号需要写上去,这是表示输出字符串。用echo命令将”helloworld”输出到标准输入,然后用管道的方式执行jar,将标准输入的字符串压缩到HDFShello.txt。“org.apache.hadoop.io.compress.GzipCodec”,这个是HadoopGzip压缩器类的类名。压缩完毕之后,执行cat,检查hello.txt内容,这时候显示的是乱码,因为原始内容已经被压缩了。然后再执行“./bin/hadoopfs -cat hello.txt | gunzip”,这次会显示出”hello,world!”,因为管道命令gunzip会将压缩文件的内容进行解压缩然后输出。

4从文件到文件的解压缩

4.1 文件和目录结构

这个程序把压缩文件压解缩到另外一个文件。创建目录~/dcprsf2f存放源代码、编译和打包结果。在dcprsf2f目录下,有两个子目录,分别是src目录和classes目录,src目录存放Java源代码,class存放编译结果。在src目录下,只有一个源代码文件DcprsF2F.java

4.2 DcprsF2F.java源文件的代码


packagecom.brianchen.hadoop;


importjava.net.URI;

importjava.io.InputStream;

importjava.io.OutputStream;


importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.io.compress.CompressionCodec;

importorg.apache.hadoop.io.IOUtils;

importorg.apache.hadoop.fs.Path;

importorg.apache.hadoop.fs.FileSystem;

importorg.apache.hadoop.util.ReflectionUtils;


public classDcprsF2F{

public staticvoid main(String[] args) throws Exception{

if(args.length != 3){

System.err.println("Usage:CprsF2F cmps_name src target");

System.exit(2);

}


Class<?>codecClass = Class.forName(args[0]);

Configurationconf = new Configuration();

CompressionCodeccodec = (CompressionCodec)ReflectionUtils.newInstance(codecClass,conf);

InputStreamin = null;

OutputStreamout = null;

FileSystem fs= FileSystem.get(URI.create(args[1]), conf);

try{

in =codec.createInputStream(fs.open(new Path(args[1])),codec.createDecompressor());

out =fs.create(new Path(args[2]));

IOUtils.copyBytes(in,out, conf);

}finally{

IOUtils.closeStream(in);

IOUtils.closeStream(out);

}

}

}


4.3 编译

cd~/dcprsf2f”

jvac-cp /home/brian/usr/hadoop/hadoop-1.2.1/hadoop-core-1.2.1.jar -d./class/ src/*.java”

4.4 打包

jar-cvf dcprsf2f.jar -C ./class/ .”

4.5 执行

cd~/usr/hadoop/hadoop-1.2.1”

./bin/hadoopjar /home/brian/cprsf2f/cprsf2f.jar com.brianchen.hadoop.DcprsF2Forg.apache.hadoop.io.compress.GzipCodec hello.txt hello_dec.txt”

./bin/hadoopfs -cat hello.txt”

./bin/hadoopfs -cat hello_dec.txt”

首先需要确认Hadoop已经启动。压缩文件hello.txt5.3节创建的,在这里直接使用。将压缩文件hello.txt解压缩到文件hello_c.txt。“org.apache.hadoop.io.compress.GzipCodec”,这个是HadoopGzip压缩器类的类名。压缩完毕之后,执行cat,检查hello.txt内容,这时候显示的是乱码。然后再执行“./bin/hadoopfs -cat hello_dec.txt”,这次会显示出”hello,world!”

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部