一、压缩的本质:信息熵与冗余度

做低延迟系统这么多年,我经常被问到同一个问题:压缩到底在做什么?

说白了,压缩就是去掉冗余。你想想看,一段数据里其实有很多“废话”。比如一个文本文件里连续出现100个空格,或者一段音频里有一段静音,这些都属于冗余。

那怎么衡量一个数据能不能压缩?能压缩多少?这就引出了两个核心概念:信息熵冗余度

1.1 信息熵:数据的不确定性

信息熵这个概念,最早是香农提出来的。它衡量的是数据的不确定性。熵越高,数据越“随机”,越难压缩。熵越低,数据越“有序”,压缩空间越大。

公式很简单:

H(X) = -Σ p(x) * log₂ p(x)

其中 p(x) 是每个符号出现的概率。

举个例子:

  • 如果一段数据全是字母'A',那 p('A') = 1,熵 H = 0。这意味着完全没有不确定性,可以压缩到极致。
  • 如果一段数据里'A'和'B'各占一半,p=0.5,熵 H = 1。这意味着每个符号需要1个bit来表示。
  • 如果数据里有256种符号均匀分布,熵 H = 8。这意味着每个符号需要8个bit,也就是一个字节。

核心观点:信息熵给出了无损压缩的理论极限。你不可能压缩到比熵更小的体积,除非你愿意丢失信息(有损压缩)。

1.2 冗余度:压缩的“油水”

冗余度就是数据中可以被去掉的部分。它等于数据实际大小减去信息熵。

冗余度 = 数据大小 - 信息熵

我在项目中遇到过一种情况:一个日志文件,里面90%的内容都是重复的时间戳和IP地址。这种数据的冗余度极高,压缩比能做到50:1甚至更高。但如果是加密后的数据,看起来完全是随机的,冗余度接近0,基本压不动。

实战经验:判断一个数据能不能压缩,先看它的冗余度。如果冗余度很低,就别浪费时间了。我曾经见过有人用gzip去压缩AES加密后的数据,结果文件反而变大了——因为加密增加了熵。

1.3 常见的冗余类型

在实际系统中,冗余通常来自以下几个方面:

冗余类型 说明 例子
统计冗余 某些符号出现频率更高 英文文本中'e'远多于'z'
空间冗余 相邻数据之间存在相关性 图片中相邻像素颜色相近
时间冗余 连续帧之间变化很小 视频中相邻帧几乎一样
字典冗余 相同模式重复出现 日志中重复的URL路径

不同的冗余类型,需要用不同的压缩算法去处理。比如统计冗余适合用霍夫曼编码,空间冗余适合用差分编码或变换编码。

二、为什么需要低延迟压缩?

好,现在我们知道压缩的本质了。但问题来了:为什么要在低延迟场景下做压缩?

传统的压缩方案,比如gzip、bzip2,它们的目标是压缩比最大化。为了多压几个百分点,它们愿意花大量CPU时间去做复杂的计算。这在离线场景下没问题——你压缩一个文件,等几秒钟无所谓。

但在低延迟场景下,情况完全不同。

2.1 低延迟场景的典型需求

我参与过几个金融交易系统的项目,这些系统对延迟的要求是微秒级的。在这种场景下:

  • 网络带宽是瓶颈,需要压缩数据来减少传输时间
  • 但压缩和解压缩本身不能引入太多延迟
  • 压缩比不是第一目标,延迟和吞吐量才是

举个例子:

假设你要传输1MB的数据,网络带宽是10Gbps。不压缩的话,传输时间大约是0.8毫秒。如果用gzip压缩到200KB,压缩比5:1,但gzip压缩需要5毫秒,解压缩需要3毫秒。总延迟变成了5+0.16+3=8.16毫秒,反而更慢了。

但如果用LZ4这种轻量级算法,压缩只需要0.5毫秒,解压缩0.3毫秒,压缩到400KB。总延迟是0.5+0.32+0.3=1.12毫秒,比不压缩的0.8毫秒略高,但节省了60%的带宽。

关键权衡:低延迟压缩的核心是在压缩比和速度之间找到平衡点。不是压得越小越好,而是要在可接受的延迟预算内,尽可能减少数据量。

2.2 低延迟压缩的应用场景

我整理了几个典型的低延迟压缩场景:

  1. 金融交易:行情数据、订单流需要在微秒级内完成压缩传输
  2. 实时视频流:直播、视频会议需要低延迟编码解码
  3. 数据库日志:WAL日志、redo log需要快速压缩写入
  4. 内存数据库:数据页压缩,减少内存带宽压力
  5. 物联网:传感器数据在边缘设备上快速压缩后上传

这些场景有一个共同点:延迟是硬约束。你不能为了压缩而牺牲延迟,否则系统就不可用了。

2.3 低延迟压缩的核心挑战

嗯,这里要注意。低延迟压缩并不是简单地把算法换一下就行。它有几个核心挑战:

  • CPU开销:压缩算法需要计算,会占用CPU时间片
  • 内存访问:压缩需要读写数据,会引入缓存未命中的开销
  • 流式处理:数据是源源不断来的,不能等全部收齐再压缩
  • 硬件适配:不同硬件(CPU、GPU、FPGA)的压缩性能差异很大

避坑指南:我曾经在一个项目中,直接用了zlib的默认参数去压缩实时数据流。结果发现压缩延迟波动很大,有时候一个数据包要压几十毫秒。后来才发现,zlib的默认参数会动态调整压缩级别,导致延迟不稳定。解决方案是固定压缩级别,并且使用预分配的缓冲区,避免内存分配带来的抖动。

三、本章知识体系

为了让你更直观地理解本章的内容结构,我画了一张图:

第一章:压缩的本质与低延迟需求 压缩的本质 • 信息熵:数据不确定性的度量 • 冗余度:可压缩的空间 • 冗余类型:统计/空间/时间/字典 • 压缩极限:熵编码的理论边界 低延迟压缩需求 • 延迟约束:微秒级响应要求 • 压缩比 vs 速度的权衡 • 典型场景:金融/视频/数据库 • 核心挑战:CPU/内存/流式/硬件 核心结论 压缩 = 去掉冗余,信息熵给出理论极限 低延迟压缩 = 在延迟预算内最大化压缩收益 知识体系结构图

这张图把本章的两个核心主题串起来了。左边是压缩的理论基础,右边是低延迟场景下的实际需求。两者结合,就是我们这门课要讲的核心内容。

我的建议:如果你刚开始接触低延迟压缩,先理解信息熵和冗余度的概念。这比学具体算法更重要。因为只有理解了为什么能压缩,你才能判断该用什么算法

好了,第一章就到这里。记住一句话:压缩不是魔法,它只是把数据里的“水分”挤出去。而低延迟压缩,就是要在挤水分的同时,保证速度够快。


公众号:蓝海资料掘金营,微信deep3321