1 压缩介绍
常用的几种压缩格式:lzo,gzip,snappy,bzip2,我们简单做一下对比,方便我们在实际场景中选择不同的压缩格式。
支持特性对比:
压缩格式 | codec类 | 算法 | 扩展名 | 多文件 | splitable | native | 工具 | hadoop自带 |
---|---|---|---|---|---|---|---|---|
gzip | GzipCodec | deflate | .gz | 否 | 否 | 是 | gzip | 是 |
bzip2 | Bzip2Codec | bzip2 | .bz2 | 是 | 是 | 否 | bzip2 | 是 |
lzo | LzopCodec | lzo | .lzo | 否 | 是 | 是 | lzop | 否 |
snappy | SnappyCodec | snappy | .snappy | 否 | 否 | 是 | 无 | 否 |
说明:
- 压缩相关codec实现在org.apache.hadoop.io.compress包下面
- gzip算法hadoop内置支持,使用时直接处理文本数据一样,使用方便,压缩比高,缺点就是不支持split。如果压缩后文件与块大小相当,可以考虑使用gzip压缩,比如:小时原始日志压缩成gzip文件,使用方便。
- bzip2 支持split,压缩比高,支持多文件,缺点就是慢。
- lzo 压缩/解压速度也比较快,合理的压缩率;支持split(需要建索引,文件修改后需要重新建索引),支持hadoop native库,需要自己安装;
- snappy 压缩/解压速度也比较快,合理的压缩率,不支持split,支持hadoop native库,需要自己安装。可以用于map中间结果的压缩。
2 性能对比
压缩格式 | 压缩比 | 压缩速率 | 解压速率 |
---|---|---|---|
gzip | 13.4% | 21 MB/s | 118 MB/s |
lzo | 20.5% | 135 MB/s | 410 MB/s |
snappy | 22.2% | 172 MB/s | 409 MB/s |
bzip2 | 13.2% | 2.4MB/s | 9.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(); –返回解压缩后的字符串的字节数组
DOIT.EDU 资料来自网络收集整理,如有侵权请告知