压缩它的本质是资源的置换,是一个时间换空间,或者说是 CPU 资源换存储资源的游戏。
压缩和解压的操作都是计算密集型的操作,非常耗费 CPU 资源。如果你的应用处理业务逻辑就需要耗费大量的 CPU 资源,就不太适合再进行压缩和解压。
如果你的系统的瓶颈是磁盘的 IO 性能,CPU 资源又很闲,这种情况就非常适合在把数据写入磁盘前先进行压缩。
压缩可能发生在两个地方:Producer 端和 Broker 端。
一般来说,Producer 端压缩、Broket 端保持、Consumer 端解压缩。其中,Kafka 会将启用了哪种压缩算法封装进消息集合中,这样当 Consumer 读取到消息集合时,它自然就知道了这些消息使用的是哪种压缩算法。
如果 Broker 端进行解压缩,会对 CPU 压力较大,但可能会选择进行消息校验,从而进行解压缩。
Kafka 有 4 种压缩算法,GZIP、Snappy、LZ4 和 zstd。在吞吐量方面,LZ4 > Snappy > zstd 和 GZIP;在压缩比方面,zstd > LZ4 > GZIP > Snappy。
启用压缩
生产者程序中配置 compression.type 参数即表示启用指定类型的压缩算法。比如下面这段程序代码展示了如何构建一个开启 GZIP 的 Producer 对象:
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("acks", "all");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("compression.type", "gzip"); // 开启GZIP压缩
Producer<String, String> producer = new KafkaProducer<>(props);压缩时间
在 Kafka 中,压缩可能发生在两个地方:Producer 端和 Broker 端。
Broker 重新压缩消息的 2 种例外情况:(1) Broker 端指定了和 Producer 端不同的压缩算法;(2) Broker 端发生了消息格式转换。
一般来说,Producer 端压缩、Broket 端保持、Consumer 端解压缩。其中,Kafka 会将启用了哪种压缩算法封装进消息集合中,这样当 Consumer 读取到消息集合时,它自然就知道了这些消息使用的是哪种压缩算法。
如果 Broker 端进行解压缩,会对 CPU 压力较大,但可能会选择进行消息校验,从而进行解压缩。
不同的压缩算法
Kafka 有 4 种压缩算法,GZIP、Snappy、LZ4 和 zstd。
在吞吐量方面,LZ4 > Snappy > zstd 和 GZIP;在压缩比方面,zstd > LZ4 > GZIP > Snappy。
最佳实践
如果 CPU 存在富裕,可以选择 zstd;如果 CPU 不富裕,那么就不进行压缩,否则服务本身可用性降低。