0、压缩编解码器总结
压缩格式 | 工具 | 算法 | 扩展名 | 是否可切分 | 所对应的类 | 优势 |
---|---|---|---|---|---|---|
DEFALTE | 无 | DEFLATE | .deflate | 否 | org.apache.hadoop.io.compress.DefaultCodec | 压缩比高 |
gzip | gzip | DEFLATE | .gz | 否 | org.apache.hadoop.io.compress.GzipCodec | |
bzip2 | bzip2 | bzip2 | .bz2 | 是(逻辑切) | org.apache.hadoop.io.compress.BZip2Codec | |
LZO | lzop | LZO | .lzo | 是(加索引) | com.hadoop.compression.lzo.LzopCodec | 压缩速度快 |
LZ4 | 无 | LZ4 | .lz4 | 否 | org.apache.hadoop.io.compress.Lz4Codec | |
Snappy | 无 | Snappy | .snappy | 否 | org.apache.hadoop.io.compress.SnappyCodec |
1、测试代码(由于Snappy需要重新编译hadoop源码,故无法测试)
public class TestCodec {
public static void main(String[] args) {
Class[] clazzes = {
DeflateCodec.class,
GzipCodec.class,
BZip2Codec.class,
Lz4Codec.class,
LzopCodec.class
};
for (Class clazz : clazzes){
testCompress(clazz);
testDecompress(clazz);
}
}
//压缩
public static void testCompress(Class clazz) {
try {
long start = System.currentTimeMillis();
Configuration conf = new Configuration();
//通过反射获取CompressionCodec对象
CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(clazz, conf);
//获得文件扩展名
String ext = codec.getDefaultExtension();
//通过codec获取输出流,将文件进行压缩
CompressionOutputStream cos = codec.createOutputStream(new FileOutputStream("f:/codec/compress/dw.txt" + ext));
//获取输入流
FileInputStream fis = new FileInputStream("f:/codec/duowan.txt");
IOUtils.copyBytes(fis, cos, 1024);
fis.close();
cos.close();
System.out.print(ext + "的压缩时间:" + (System.currentTimeMillis() - start));
File file = new File("f:/codec/compress/dw.txt" + ext);
System.out.print(",压缩后的文件大小:" + file.length());
} catch (Exception e) {
e.printStackTrace();
}
}
//解压
public static void testDecompress(Class clazz) {
try {
long start = System.currentTimeMillis();
Configuration conf = new Configuration();
//通过反射获取CompressionCodec对象
CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(clazz, conf);
//获得文件扩展名
String ext = codec.getDefaultExtension();
//通过codec获取输入流,将文件进行解压
CompressionInputStream cis = codec.createInputStream(new FileInputStream("f:/codec/compress/dw.txt" + ext));
//获取输入流
FileOutputStream fos = new FileOutputStream("f:/codec/compress/dw2.txt");
IOUtils.copyBytes(cis, fos, 1024);
IOUtils.closeStream(fos);
System.out.println(",解压时间:" + (System.currentTimeMillis() - start));
} catch (Exception e) {
e.printStackTrace();
}
}
}
2、压缩时长:lz4 < lzo < gzip < deflate < bzip2
3、压缩比:lzo < lz4 < gzip < deflate < bzip2(gz和deflate只是文件头有区别)
注:压缩比 = (被压文件 - 压缩文件) / 被压文件,压缩文件越大,压缩比越小
4、解压时长:lzo < lz4 < gzip < deflate < bzip2
5、总结:
压缩比高:deflate,gzip,bzip2
压缩速度快:lz4,lzo
综合考虑,gzip是最流行的压缩编解码器
6、压缩类型的选择:
(1)使用SeqFile等容器文件格式 + 快速压缩工具(lzo,lz4,snappy),效率最高!
(2)使用支持切分的压缩格式(bzip2,lzo),即支持逻辑切割的压缩格式
注:lzo只有在添加索引的时候才支持切割,即lzo文件的预处理,添加索引代码如下:
public class TestLzoIndex {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
conf.set("io.compression.codecs", "org.apache.hadoop.io.compress.LzopCodec");
LzoIndexer indexer = new LzoIndexer(conf);
indexer.index(new Path("file:///f:/codec/compress/src.log.lzo"));
}
}
(3)存储未压缩的文件,效率最低!