生产者压缩算法
怎么压缩?
- 压缩(compression)秉承了用时间去换空间的经典 trade-off 思想,具体来说就是用 CPU 时间去换磁盘空间或网络 I/O 传输量,希望以较小的 CPU 开销带来更少的磁盘占用或更少的网络 I/O 传输。
- 目前 Kafka 共有两大类消息格式,社区分别称之为 V1 版本和 V2 版本。
- 不论是哪个版本,Kafka 的消息层次都分为两层:消息集合(message set)以及消息(message)。
- 一个消息集合中包含若干条日志项(record item),而日志项才是真正封装消息的地方。
- Kafka 底层的消息日志由一系列消息集合日志项组成。
- Kafka 通常不会直接操作具体的一条条消息,它总是在消息集合这个层面上进行写入操作。
- V2 版本有一个和压缩息息相关的改进,就是保存压缩消息的方法发生了变化。
- 之前 V1 版本中保存压缩消息的方法是把多条消息进行压缩然后保存到外层消息的消息体字段中;
- 而 V2版本的做法是对整个消息集合进行压缩。
- 显然后者应该比前者有更好的压缩效果。
何时压缩?
- 在 Kafka 中,压缩可能发生在两个地方:生产者端和 Broker 端。
- 生产者程序中配置 compression.type 参数即表示启用指定类型的压缩算法。
- 其实大部分情况下 Broker 从 Producer 端接收到消息后仅仅是原封不动地保存而不会对其进行任何修改,有两种例外情况就可能让 Broker 重新压缩消息。
- Broker 端指定了和 Producer 端不同的压缩算法。
- Broker 端发生了消息格式转换。
何时解压缩?
- 通常来说解压缩发生在消费者程序中,也就是说 Producer 发送压缩消息到 Broker 后,Broker 照单全收并原样保存起来。
- 当 Consumer 程序请求这部分消息时,Broker 依然原样发送出去,当消息到达 Consumer 端后,由 Consumer 自行解压缩还原成之前的消息。
- Kafka 会将启用了哪种压缩算法封装进消息集合中,这样当 Consumer 读取到消息
集合时,它自然就知道了这些消息使⽤的是哪种压缩算法。 - 除了在 Consumer 端解压缩,Broker 端也会进行解压缩。
- 注意了,这和消息格式转换时发生的解压缩是不同的场景。
- 每个压缩过的消息集合在 Broker 端写入时都要发生解压缩操作,目的就是为了对消息执行各种验证。
- 这种解压缩对 Broker 端性能是有一定影响的,特别是对 CPU 的使用率而言。
各种压缩算法对比
- 看一 个压缩算法的优劣,有两个重要的指标:
- 压缩比
- 原先占 100 份空间的东西经压缩之后变成了占 20 份空间,那么压缩比就是 5,显然压缩比越高越好;
- 压缩 / 解压缩吞吐量
- 每秒能压缩或解压缩多少 MB 的数据。
- 同样地,吞吐量也是越高越好。
- 压缩比
- Facebook Zstandard 官网提供的一份压缩算法 benchmark 比较结果:
- 在吞吐量方面:LZ4 > Snappy > zstd 和 GZIP;
- 在压缩比方面:zstd > LZ4 > GZIP > Snappy;
- 使用 Snappy 算法占用的网络带宽最多,zstd 最少,这是合理的,毕竟 zstd 就是要提供超高的压缩比;
- 在 CPU 使用率方面,各个算法表现得差不多,只是在压缩时 Snappy 算法使用的 CPU 较多一些,而在解压缩时 GZIP 算法则可能使用更多的 CPU。