压缩算法分析(Gzip/Snappy/Lz4/ZSTD)

一、概况

当我们进行数据传输或者数据存储等场景的时候,如果数据量比较大的话,那么操作就会随着数据量的变大而变得缓慢以及耗费资源。如果是数据传输,那么大的数据量在进行网络传输的时候会非常耗时;如果是进行数据的持久化,存储到数据库,那么也会非常耗费存储空间。

对于大数据而言,最直接的优化方式,就是对数据进行一个压缩操作处理,减少数据尺寸。时长为了节省存储资源以及操作传输加速,会对数据进行压缩加工,减少它的尺寸,从而提高各项效率。

压缩类别:压缩可以分为有损压缩和无损压缩。有损压缩算法通过移除在保真情形下需要大量的数据去存储的小细节,从而使文件变小。在有损压缩里,因某些必要数据的移除,恢复原文件是不可能的。有损压缩主要用来存储图像和音频文件,同时通过移除数据可以达到一个比较高的压缩率。无损压缩,也使文件变小,但对应的解压缩功能可以精确的恢复原文件,不丢失任何数据。

时下互联网内比较流行的无损压缩算法有Gzip、Snappy、LZ4以及ZSTD等,前几种提到的压缩算法在消息中间件Kafka中都提供了使用,可以结合具体工具进行探索使用。

场景选择:不同的场景选择不同的压缩方式,肯定没有一个一劳永逸的方法,如果选择高压缩比,那么对于cpu的性能要求要高,同时压缩、解压时间耗费也多;选择压缩比低的,对于磁盘io、网络io的时间要多,空间占据要多;对于支持分割的,可以实现并行处理。

本文主要介绍这四种无损压缩算法的基础原理以及它们各自的优缺点和适合场景,并且通过具体的业务场景进行性能对比,以此来实际的深刻理解几种压缩算法。

二、算法分析

2.1 Gzip

Gzip是一个比较大众通用的压缩算法,凭借其可观的压缩比例而被大家所熟知。Gzip全名是Gnu zip,最开始是为了Unix系统文件压缩而设计开发的,如今它的方法逻辑应用到互联网的各个方面,包括http传输压缩、nginx压缩功能以及在java中提供的gzip压缩API使用等。

Gzip压缩原理是以Deflate压缩算法为基础,而Deflate算法是LZ77压缩算法的优化和Huffman编码的一个结合使用,因此我们下面会简单介绍下基础的LZ77压缩算法和Huffman编码的原理,从而深刻理解Gzip的压缩原理。

2.1.1 LZ77

LZ77压缩算法是由Jacob Ziv 和 Abraham Lempel 于1977年提出,以此得名。

LZ77术语相关

  1. 滑动窗口:编码的过程类似算法中“滑动窗口”算法的逻辑过程,包含look ahead buffer和search buffer
  2. look ahead buffer(待检区):
  3. search buffer(搜索区):

为了编码待编码区, 编码器在滑动窗口的搜索缓冲区查找直到找到匹配的字符串。匹配字符串的开始字符串与待编码缓冲区的距离称为“偏移值”,匹配字符串的长度称为“匹配长度”。编码器在编码时,会一直在搜索区中搜索,直到找到最大匹配字符串,并输出(o, l ),其中o是偏移值, l是匹配长度。然后窗口滑动l,继续开始编码。如果没有找到匹配字符串,则输出(0, 0, c),c为待编码区下一个等待编码的字符,窗口滑动“1”。

LZ77压缩逻辑示例

  • 示例元素:ABCCABCAD
  • 搜索区长度:5
  • 待检区长度:3
  1. 搜索前,搜索区和待检区以及字符串状态,搜区区为空,待检区内进入了三个元素,如图所示
    在这里插入图片描述

  2. 待检区检查第一个元素A,发现搜索区没有匹配项目,因此元素A按照原码记录,如下图
    在这里插入图片描述

  3. 依次检查后面的元素B和C,发现搜索区没有与之相匹配的重复元素,因此按照源码记录
    在这里插入图片描述
    在这里插入图片描述

  4. 下面检查元素C,发现在搜索区有该元素,因此使用(offset,length)编码元素C,即(1,1),如图:
    在这里插入图片描述

  5. 后面进行元素A匹配,发现匹配项,然后在继续一位元素B,即AB元素,也发现匹配,最后找到ABC在搜素区找到匹配项,因此使用(4,3)进行对ABC元素的编码,后续查找方式类似,知道遍历元素末尾
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

当所有元素遍历完毕之后,会得到一个新的经过编码的表示串,即:ABC(1,1)(4,3)(2,1)D,可以看出LZ77算法的中心思想就是利用数据的重复结构信息来进行数据压缩。

通过LZ77对数据进行初步的压缩之后,后续通过Huffman编码再次进行数据压缩,下面看下Huffman coding的原理。

2.1.2 Huffman coding

相信很多人对Huffman这个词并不陌生,因为它是大学里面数据结构课程的一个算法内容。该算法依据元素出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。

哈夫曼编码,核心逻辑是根据使用频率来最大化节省字符(编码)的存储空间。通过较大的字符串表示频率小的字符串,相应的通过较小字符串表示出现频率比较大的字符串,通过这个差值减少元素串的尺寸。

下面以元素串【emm tell me the truth】为例子,演示Huffman编码过程以及结果:

  1. 首先扫面原元素串,统计每个元素的出现频率信息
    在这里插入图片描述
  2. 依据二叉树的规则,将元素信息以出现频率为权重,构造一个最优二叉树,示例树如图所示:
    在这里插入图片描述
  3. 根据既定路径规则(左子树路径:0,右子树路径:1),得到每个元素的Huffman编码如下所示:
    在这里插入图片描述
    上图展示了元素串:【emm tell me the truth】,经过Huffman编码后用位串表示:【01 110 110 00 01 100 100 110 01 00 101 01 00 1110 1111 00 101】。可以看到Huffman编码占用比较少的位来描述元素信息,且频率高的元素使用的描述位比较少。

2.2 Snappy

2.3 LZ4

LZ4以其超高的吞吐量而出名,它的压缩和解压缩速度非常快,其底层压缩原理特使参考了LZ77算法,在其基础之上做了优化,可以粗暴的理解为是一个用16k大小哈希表储存字典并简化检索的LZ77。

在LZ77算法进行压缩时,耗时最多的部分是在字典中找到待搜索缓存中最长的匹配字符。若是字典和待搜索缓存过短,则能找到匹配的几率就会很小。所以LZ4对LZ77针对匹配算法进行了改动。

首先,LZ4算法的字典是一张哈希表。 字典的key是一个4字节的字符串,每个key只对应一个槽,槽里的value是这个字符串的位置。

LZ4没有待搜索缓存, 而是每次从输入文件读入四个字节, 然后在哈希表中查找这字符串对应的槽,下文称这个字符串为现在字符串。如果已经到最后12个字符时直接把这些字符放入输出文件。如果槽中没有赋值,那就说明这四个字节第一次出现, 将这四个字节和位置加入哈希表, 然后继续搜索。如果槽中有赋值,那就说明我们找到了一个匹配值。

下图展示了LZ4压缩的数据结构:

  • Token:令牌长为1字节,其中前4个字为字面长度(literal length),而其后4个字为匹配长度(match length)
  • Literal length:literal长度超长补充
  • literals:非编码元素
  • Offset:偏差,和LZ77中的offset一样的含义,表示距离重复串的index
  • Match length:match串长度超长补充
    在这里插入图片描述

2.4 ZSTD

三、参考文章

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值