压缩格式gzip/snappy/lzo/bzip2 比较与总结

 

1 压缩介绍

常用的几种压缩格式:lzo,gzip,snappy,bzip2,我们简单做一下对比,方便我们在实际场景中选择不同的压缩格式。

支持特性对比:

压缩格式codec类算法扩展名多文件splitablenative工具hadoop自带
gzipGzipCodecdeflate.gzgzip
bzip2Bzip2Codecbzip2.bz2bzip2
lzoLzopCodeclzo.lzolzop
snappySnappyCodecsnappy.snappy

说明:

  • 压缩相关codec实现在org.apache.hadoop.io.compress包下面
  • gzip算法hadoop内置支持,使用时直接处理文本数据一样,使用方便,压缩比高,缺点就是不支持split。如果压缩后文件与块大小相当,可以考虑使用gzip压缩,比如:小时原始日志压缩成gzip文件,使用方便。
  • bzip2 支持split,压缩比高,支持多文件,缺点就是慢。
  • lzo 压缩/解压速度也比较快,合理的压缩率;支持split(需要建索引,文件修改后需要重新建索引),支持hadoop native库,需要自己安装;
  • snappy 压缩/解压速度也比较快,合理的压缩率,不支持split,支持hadoop native库,需要自己安装。可以用于map中间结果的压缩。

2 性能对比

压缩格式压缩比压缩速率解压速率
gzip13.4%21 MB/s118 MB/s
lzo20.5%135 MB/s410 MB/s
snappy22.2%172 MB/s409 MB/s
bzip213.2%2.4MB/s9.5MB/s

是否压缩数据以及使用何种压缩格式对性能具有重要的影响,一般原则:

  • 需要平衡压缩和解压缩数据所需的能力、读写数据所需的磁盘 IO,以及在网络中发送数据所需的网络带宽。正确平衡这些因素有赖于集群和数据的特征,以及您的
    使用模式。
  • 如果数据已压缩(例如 JPEG 格式的图像),则不建议进行压缩。事实上,结果文件实际上可能大于原文件。
  • GZIP 压缩使用的 CPU 资源比 Snappy 或 LZO 更多,但可提供更高的压缩比。GZIP 通常是不常访问的冷数据的不错选择。而 Snappy 或 LZO 则更加适合经常访问的热数据。
  • BZip2 还可以为某些文件类型生成比 GZip 更多的压缩,但是压缩和解压缩时会在一定程度上影响速度。HBase 不支持 BZip2 压缩。
  • Snappy 的表现通常比 LZO 好。应该运行测试以查看您是否检测到明显区别。
  • 对于 MapReduce,如果您需要已压缩数据可拆分,BZip2、LZO 和 Snappy 格式都可拆分,但是 GZip 不可以。可拆分性与 HBase 数据无关。
  • 对于 MapReduce,可以压缩中间数据、输出或二者。相应地调整您为 MapReduce 作业提供的参数。

 

3 zip、GZIP、QuickLz、snappy、lzf、jzlib使用

1、ZIP、 GZIP  计算机文件压缩算法,JDK中java.util.zip.*中实现。主要包括ZipInputStream/ ZipOutputStream、GZipInputStream/ ZipOutputStream。

2、QuickLZ是一个号称世界压缩速度最快的压缩库,并且也是个开源的压缩库,其遵守 GPL 1, 2 或 3协议。

3、Snappy是一个 C++的用来压缩和解压缩的开发包,其目标不是最大限度压缩,而且不兼容其他压缩格式。旨在提供高速压缩速度和合理的压缩率。在64位模式的 Core i7 处理器上,可达每秒250~500兆的压缩速度。在 Google 内部被广泛的使用,从 BigTable到 MapReduce以及内部的RPC 系统。

4、LZF采用类似lz77和lzss的混合编码,针对字符串压缩算法。 

5、JZLIB是纯java的开源解压、压缩包,与JDK中ZLIB类似。

 

3.1 预选解压缩类库使用介绍--ZIP

压缩

String  s = “这是一个用于测试的字符串”;

ByteArrayOutputStream out = new ByteArrayOutputStream();

ZipOutputStreamzout = new ZipOutputStream(out);

zout.putNextEntry(new ZipEntry("0"));

zout.write(s.getBytes());

zout.closeEntry();

byte[] compressed = out.toByteArray();   --返回压缩后的字符串的字节数组

解压

ByteArrayOutputStream out = new ByteArrayOutputStream();

ByteArrayInputStream in = new ByteArrayInputStream(compressed);

ZipInputStreamzin = new ZipInputStream(in);

zin.getNextEntry();

byte[] buffer = new byte[1024];

intoffset = -1;

while ((offset = zin.read(buffer))!= -1) {

       out.write(buffer, 0, offset);

}

byte[] uncompressed = out.toByteArray();   --返回解压缩后的字符串的字节数组

 

3.2 预选解压缩类库使用介绍--GZIP

压缩

String  s = “这是一个用于测试的字符串”;

ByteArrayOutputStream out = new ByteArrayOutputStream();

GZipOutputStream gout = new GZipOutputStream(out);

gout.write(s.getBytes());

byte[] compressed = out.toByteArray();   --返回压缩后的字符串的字节数组

解压

ByteArrayOutputStream out = new ByteArrayOutputStream();

ByteArrayInputStream in = new ByteArrayInputStream(compressed);

GZipInputStreamgzin =newGZipInputStream(in);

byte[] buffer = new byte[1024];

intoffset = -1;

while ((offset = gzin.read(buffer)) != -1) {

       out.write(buffer, 0, offset);

}

byte[] uncompressed = out.toByteArray();   --返回解压缩后的字符串的字节数组

 

3.3 预选解压缩类库使用介绍--QuickLZ

压缩

String  s = “这是一个用于测试的字符串”;

--Level 1

byte[] compressed =QuickLZ.compress(s.getBytes(), 1);   --返回压缩后的字符串的字节数组

--Level3

byte[] compressed =QuickLZ.compress(s.getBytes(), 3);   --返回压缩后的字符串的字节数组

解压

byte[] uncompressed =QuickLZ.decompress(compressed );   --返回解压缩后的字符串的字节数组

 

3.4 预选解压缩类库使用介绍--Snappy

压缩

String  s = “这是一个用于测试的字符串”;

byte[] compressed =Snappy.compress(s.getBytes());   --返回压缩后的字符串的字节数组

解压

byte[] uncompressed =Snappy.uncompress(compressed );   --返回解压缩后的字符串的字节数组

 

4.5 预选解压缩类库使用介绍-- LZF

压缩

String  s = “这是一个用于测试的字符串”;

byte[] compressed = LZFEncoder.encode(s.getBytes());   --返回压缩后的字符串的字节数组

解压

byte[] uncompressed = LZFDecoder.decode(compressed );   --返回解压缩后的字符串的字节数组

 

3.6 预选解压缩类库使用介绍-- JZLIB

压缩

String  s = “这是一个用于测试的字符串”;

ByteArrayOutputStream out = new ByteArrayOutputStream();

DeflaterOutputStreamdout = new DeflaterOutputStream(out);

dout.write(s.getBytes());

dout.close();         --需要先关闭

byte[] compressed = out.toByteArray();   --返回压缩后的字符串的字节数组

解压

ByteArrayOutputStream out= new ByteArrayOutputStream();

ByteArrayInputStream  in =  new ByteArrayInputStream(compressedStr);

InflaterInputStream input = new InflaterInputStream(in);

byte[] buffer = new byte[1024];

intoffset = -1;

while ((offset = input.read(buffer)) != -1) {

        out.write(buffer, 0, offset);

}

out.close();   --需要先关闭

byte[] uncompressed = out.toByteArray();   --返回解压缩后的字符串的字节数组

 

4. 参考

http://www.hainiubl.com/topics/26

http://www.cnblogs.com/panfeng412/archive/2012/12/24/applications-scenario-summary-of-compression-algorithms.html

https://blog.csdn.net/MCpang/article/details/41141261

  • 0
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MapReduce是一种用于处理大规模数据集的并行计算框架,它可将任务分解为多个子任务,并在分布式系统中进行并行处理。在MapReduce中,我们可以使用不同的压缩算法来压缩写入和读取数据的文件,这样可以提高存储和传输效率。 Gzip是一种常见的压缩算法,它通过使用DEFLATE算法对文件进行压缩。在MapReduce中,我们可以使用Gzip压缩算法来写入文件。当写入数据时,MapReduce会使用Gzip算法对数据进行压缩,并将压缩后的数据写入文件。在读取数据时,MapReduce会自动解压缩文件并将数据加载到内存中进行处理。 Snappy是一种快速压缩算法,它在压缩和解压缩数据时具有较高的速度。在MapReduce中,如果我们需要更高的压缩和解压缩速度,可以使用Snappy压缩算法来写入文件。与Gzip相似,MapReduce会使用Snappy算法对数据进行压缩,并在读取数据时自动解压缩文件。 LZO是另一种常见的压缩算法,它在压缩数据时提供了较高的压缩比和较快的压缩速度。在MapReduce中,如果数据的压缩比很重要,我们可以选择使用LZO压缩算法来写入文件。MapReduce会使用LZO算法对数据进行压缩,并在读取数据时自动解压缩文件。 总之,MapReduce可以使用不同的压缩算法(如GzipSnappyLZO)来写入和读取文件。使用不同的压缩算法可以根据需求平衡存储空间和计算速度。如果需要高压缩比或更高的速度,可以选择合适的压缩算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值