2、数据压缩基础理论:信息熵、香农定理、无损压缩与有损压缩的取舍、压缩比与吞吐量的平衡

各位同学,咱们今天聊点硬核的。数据压缩,说白了就是给数据「减肥」。高频交易里,一秒钟几万笔行情,你不压缩,网络带宽分分钟被撑爆。我当年刚入行时,就吃过这个亏——裸数据直接往网线里塞,结果延迟飙升,被老板骂得狗血淋头。

所以,这一章咱们把压缩的底裤扒干净。从信息熵这个「理论天花板」讲起,再到香农定理、无损有损的取舍,最后聊聊压缩比和吞吐量这对冤家怎么平衡。嗯,内容有点干,但全是实战经验。

2.1 信息熵:压缩的「理论天花板」

信息熵这个概念,是香农老爷子在1948年提出来的。它衡量的是信息的不确定性。你想想看,一个数据源,如果每个符号出现的概率都一样,那它的熵就最大,最难压缩。反过来,如果某个符号出现概率极高,那熵就很小,压缩空间就大。

公式很简单:

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

其中 H(X) 是熵,单位是比特。p(x) 是符号 x 出现的概率。

举个例子

假设行情数据里,买一价和卖一价经常重复出现。如果「买一价=10.00」这个值出现了 90% 的次数,那它的信息量就很小。用熵算一下:

H = - (0.9 * log₂ 0.9 + 0.1 * log₂ 0.1)
  ≈ - (0.9 * (-0.152) + 0.1 * (-3.322))
  ≈ 0.469 比特

也就是说,理论上每个符号平均只需要 0.469 比特就能表示。但如果你用原始的 32 位浮点数去存,那就是 32 比特,浪费了 98.5% 的空间。

核心观点:信息熵告诉你,压缩的极限在哪里。任何无损压缩算法,都不可能低于这个值。这是物理定律,别想着突破它。

我的经验:我在做行情数据压缩时,第一步就是算熵。如果算出来熵是 0.5 比特,但实际压缩后是 1.2 比特,说明算法还有优化空间。如果已经接近 0.5 了,那就别折腾了,换有损压缩吧。

2.2 香农定理:信道容量与压缩的关系

香农定理讲的是信道容量。公式是:

C = B * log₂(1 + S/N)

其中 C 是信道容量(比特/秒),B 是带宽(赫兹),S/N 是信噪比。

这个定理告诉我们:无论你怎么压缩,传输速率不能超过信道容量。说白了,你压缩得再狠,网线就那么大水管,水流量是有上限的。

我当年在搭建跨机房行情传输链路时,就遇到过这个问题。机房 A 到机房 B 的专线带宽只有 10Gbps,但行情数据峰值能达到 20Gbps。怎么办?

  • 方案一:升级带宽,但成本翻倍,老板不同意。
  • 方案二:压缩数据,把 20Gbps 压到 5Gbps,留出余量。

我们选了方案二。但压缩算法不能太复杂,否则 CPU 扛不住。这就是后面要讲的「压缩比与吞吐量的平衡」。

注意:香农定理是理论极限。实际工程中,你永远达不到这个极限。因为编码、调制、纠错都有开销。我一般留 20% 的余量,比如信道容量 10Gbps,我只敢用到 8Gbps。

2.3 无损压缩与有损压缩的取舍

高频交易里,数据压缩分两种:无损和有损。

无损压缩:解压后数据完全不变。适合订单簿、成交记录这些必须精确的数据。常用算法有:

  • LZ4:压缩比一般(2:1 左右),但速度极快。我常用它做实时压缩。
  • Zstd:压缩比高(3:1 到 5:1),速度也不错。适合批量压缩。
  • 差分编码:存差值而不是原始值。比如行情价格,相邻两笔可能只差 0.01,存差值比存原始值省很多空间。

有损压缩:解压后数据有微小误差,但整体趋势不变。适合 K 线、指标计算这些对精度不敏感的场景。常用方法:

  • 量化:把浮点数转成整数。比如价格保留 2 位小数,丢掉后面的精度。
  • 降采样:把 1 秒 1000 笔的 tick 数据,降成 1 秒 10 笔的 OHLC 数据。
  • 死区压缩:变化小于某个阈值时,不记录。比如价格波动小于 0.01 时,直接忽略。

取舍原则

  • 交易逻辑依赖的数据 → 无损压缩
  • 回测、分析用的数据 → 有损压缩
  • 实时传输 → 优先保证速度,压缩比次之
  • 历史存储 → 优先保证压缩比,速度次之

避坑指南:我曾经在实时行情传输中用了 Zstd 的高压缩级别,结果 CPU 打满,延迟从 10 微秒飙到 100 微秒。后来换成 LZ4,虽然压缩比低了点,但延迟稳定在 5 微秒。记住:高频交易里,延迟比压缩比重要 100 倍

2.4 压缩比与吞吐量的平衡

压缩比和吞吐量,就像鱼和熊掌。你追求高压缩比,算法就复杂,CPU 就忙,吞吐量就下降。你追求高吞吐量,算法就简单,压缩比就低。

咱们用数据说话。假设 CPU 是 Intel Xeon Gold 6248,单核 2.5GHz:

算法 压缩比 压缩速度 (MB/s) 解压速度 (MB/s)
LZ4 2.1:1 1500 4500
Zstd (level 1) 2.8:1 800 2500
Zstd (level 10) 3.5:1 200 2500
gzip (level 6) 3.2:1 100 400

你看,LZ4 压缩速度是 1500 MB/s,但压缩比只有 2.1:1。Zstd level 10 压缩比 3.5:1,但速度只有 200 MB/s。怎么选?

我的建议

  • 实时行情传输:用 LZ4。因为行情数据量不大(每秒几 MB 到几十 MB),LZ4 的速度足够,而且解压极快,不增加延迟。
  • 历史数据存储:用 Zstd level 3-5。压缩比高,存储成本低。解压速度也还行,回测时不会太慢。
  • 跨机房传输:用 Zstd level 1。带宽有限,需要压缩比高一点,但 CPU 不能太忙,否则影响其他任务。

平衡公式

有效吞吐量 = 压缩速度 × 压缩比

比如 LZ4 的有效吞吐量 = 1500 × 2.1 = 3150 MB/s。Zstd level 1 的有效吞吐量 = 800 × 2.8 = 2240 MB/s。虽然 LZ4 压缩比低,但有效吞吐量反而更高。这就是为什么实时场景下 LZ4 更受欢迎。

注意:别只看压缩比。我见过有人为了省 10% 的存储空间,用了高压缩级别,结果回测时解压成了瓶颈,一天的数据要解压半小时。嗯,得不偿失。

2.5 实战:如何选择压缩策略

说了这么多理论,咱们来点实际的。假设你正在设计一个高频交易系统,数据流如下:

  1. 行情接收:从交易所接收 tick 数据,每秒 1000 笔。
  2. 实时处理:计算指标、生成信号。
  3. 数据存储:把原始数据存到磁盘,供回测用。
  4. 跨机房同步:把数据传到灾备机房。

我的策略是:

  • 行情接收 → 实时处理:不压缩。因为数据量小(每秒几 KB),压缩反而增加延迟。
  • 实时处理 → 数据存储:用 Zstd level 3。压缩比 3:1 左右,解压速度 2000 MB/s,回测时够用。
  • 实时处理 → 跨机房同步:用 LZ4。带宽有限,但延迟更重要。LZ4 解压快,不拖累交易。

我的经验:我曾经在跨机房同步时用了 Zstd level 5,结果压缩速度跟不上行情峰值,导致数据积压。后来改成 LZ4,虽然带宽占用多了 30%,但延迟从 50 毫秒降到了 5 毫秒。记住:在高频交易里,延迟就是金钱

好了,这一章的内容就到这里。信息熵告诉你压缩的极限,香农定理告诉你传输的极限,无损有损的取舍看场景,压缩比和吞吐量的平衡看需求。下一章咱们聊聊具体的压缩算法实现,包括差分编码、游程编码、LZ4 的实战用法。到时候我会手写代码,带你们跑一遍。