常见数据压缩算法压缩
文件压缩主要有两个好处,一是减少了存储文件所占空间,另一个就是为数据传输提速。在Hadoop大数据的背景下,这两点尤为重要,那么我现在就先来了解下hadoop中的文件压缩。hadoop里支持很多种压缩格式,我们看一个表格:
LZO和LZ4算法已经不在Hadoop1.x中使用了。
1、DEFLATE是同时使用了LZ77与哈夫曼编码的一个无损数据压缩算法,源代码可以在zlib库中找到。gzip是以DEFLATE算法为基础扩展出来的一种算法。
2、压缩算法都是空间和时间的转换,更快压缩时间还是更小的压缩比。可以通过参数来指定,-1意味着速度,-9意味着空间。
拿gzip做个例子,下面就意味着更快速的压缩:gzip -1 file
3、gzip在时间和空间上的比较适中,bzip2压缩比gzip更有效,但是速度更慢。bzip2的解压速度比它的压缩速度要快。但是和其他压缩格式相比又是最慢的,但是压缩效果明显是最好的。snappy和LZ4的解压速度比LZO好很多。
4、splittable表示压缩格式是否可以被分割,也就是说是否支持随机读。压缩数据是否能被mapreduce使用,压缩数据是否能被分割就很关键了。
目前在Hadoop中用得比较多的有lzo,gzip,snappy,bzip2这4种压缩格式。下面是4种压缩格式的特征的比较。
Codec实现类
org.apache.hadoop.io.compress
CompressionCodec是压缩和解压缩的接口。以下是该接口的实现类。
CompressionCodec方法
CompressionCodec有两个方法用来压缩和解压
压缩:通过createOutputStream(OutputStream out)方法获得CompressionOutputStream对象
解压:通过createlnputStream(InputStream in)方法获得Compressionlnputstream对象
编写下面的例子进行比较
dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。
拷贝生成一个
512M的文件
[root@master liguodong]# dd
if=/dev/zero
of=
data bs=1024k count=512
记录了
512+
0 的读入
记录了
512+
0 的写出
536870912字节(
537 MB)已复制,
0.557151 秒,
964 MB/秒
[root@master liguodong]# ll
data
-rw-r
--r-- 1 root root 536870912 6月 5 19:11 data
[root@master liguodong]# pwd
/liguodong
[root@master liguodong]# ls
codec.jar
data dir jni
package Compress
;
import java
.io.FileInputStream;
import java
.io.FileOutputStream;
import java
.io.IOException;
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.mapreduce.Job;
import org
.apache.hadoop.util.ReflectionUtils;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//
1、配置
Configuration configuration = new Configuration()
;
Job job = Job
.getInstance(configuration,
"Codec")
;
//
2、打包运行必须执行的方法
job
.setJarByClass(Test
.class)
;
//String codecClassName =
"org.apache.hadoop.io.compress.BZip2Codec";
String codecClassName =
"org.apache.hadoop.io.compress.GzipCodec";
Class<?> clsClass = Class
.forName(codecClassName)
;
CompressionCodec codec = (CompressionCodec)
ReflectionUtils
.newInstance(clsClass, configuration)
;
String inputFile =
"/liguodong/data";
String outFile = inputFile + codec
.getDefaultExtension()
;//获得默认扩展名
FileOutputStream fileOut = new FileOutputStream(outFile)
;
CompressionOutputStream
out = codec
.createOutputStream(fileOut)
;
FileInputStream
in = new FileInputStream(inputFile)
;
IOUtils
.copyBytes(
in,
out,
4096 ,false)
;
in.close()
;
out.close()
;
}
}