GZIP、LZO、Zippy/Snappy是常用的几种压缩算法,各自有其特点,因此适用的应用场景也不尽相同。这里结合相关工程实践的情况,做一次小结。
压缩算法的比较
以下是Google几年前发布的一组测试数据(数据有些老了,有人近期做过测试的话希望能共享出来):
Algorithm | % remaining | Encoding | Decoding |
GZIP | 13.4% | 21 MB/s | 118 MB/s |
LZO | 20.5% | 135 MB/s | 410 MB/s |
Zippy/Snappy | 22.2% | 172 MB/s | 409 MB/s |
注:来自《HBase: The Definitive Guide》
其中:
1)GZIP的压缩率最高,但是其实CPU密集型的,对CPU的消耗比其他算法要多,压缩和解压速度也慢;
2)LZO的压缩率居中,比GZIP要低一些,但是压缩和解压速度明显要比GZIP快很多,其中解压速度快的更多;
3)Zippy/Snappy的压缩率最低,而压缩和解压速度要稍微比LZO要快一些。
BigTable和HBase中压缩算法的选择
BigTable中采用的是Zippy算法,目标是达到尽可能快的压缩和解压速度,同时减少对CPU的消耗。
HBase中,在Snappy发布之前(Google 2011年对外发布Snappy),采用的LZO算法,目标和BigTable类似;在Snappy发布之后,建议采用Snappy算法(参考《HBase: The Definitive Guide》),具体可以根据实际情况对LZO和Snappy做过更详细的对比测试后再做选择。
实际项目中的实践经验
项目中使用clearspring公司开源的基数估计的概率算法:stream-lib,用于解决去重计算问题,如UV计算等,它的特点在于:
1)一个UV的计算,可以限制在一个固定大小的位图空间内完成(不同大小,对应不同的误差率),如8K,64K;
2)不同的位图可以进行合并操作,得到合并后的UV。
当系统中维护的位图越多的时候,不管是在内存中,还是在存储系统(MySQL、HBase等)中,都会占用相当大的存储空间。因此,需要考虑采取合适的算法来压缩位图。这里分为以下两类情况:
1)当位图在内存中时,此时压缩算法的选择,必须有尽可能快的压缩和解压速度,同时不能消耗过多CPU资源,因此,适合使用LZO或Snappy这样的压缩算法,做到快速的压缩和解压;
2)当位图存储到DB中时,更关注的是存储空间的节省,要有尽可能高的压缩率,因此,适合使用GZIP这样的压缩算法,同时在从内存Dump到DB的过程也可以减少网络IO的传输开销。
总结的话
以上是对GZIP、LZO、Zippy/Snappy压缩算法特点的概括比较,以及一些实践上的方法。如有不对之处,欢迎大家指正,讨论。