使用 Spring Boot 在 Apache Kafka 中进行消息压缩
生产者通常发送基于文本的数据,例如 JSON 数据。在这种情况下,对生产者应用压缩是必不可少的。默认情况下,生产者消息以未压缩的形式传输。Kafka 压缩有两种类型。
1. 生产者级 Kafka 压缩
在生产者端启用压缩后,代理或消费者无需进行任何更改。使用 compression.type 参数,生产者可以选择是否压缩消息。压缩类型有五种选项,
- none
- gzip
- lz4
- snappy
- zstd
如果启用,则压缩由生产者客户端执行。生产者必须将消息批量处理以获得更高的吞吐量。
执行
BATCH_SIZE_CONFIG:当向同一分区发送多条记录时,生产者将尝试将记录合并为更少的请求。这样可以提高客户端和服务器的性能。字节是此选项设置的默认批处理大小。任何试图将大于此大小的记录分组的尝试都将失败。对代理的请求将包含多个批处理,每个分区一个批处理,其中包含可访问的数据以供发送。小的批处理大小将阻止批处理并可能降低吞吐量(批处理大小为零将完全禁用批处理)。由于我们总是分配提供的批处理大小的缓冲区以预期更多记录,因此非常大的批处理大小可能会更浪费内存。
LINGER_MS_CONFIG: 生产者将请求广播之间收到的所有记录编译为单个批处理请求。这通常仅在负载下发生,即记录到达的速度比发送速度快。但有时,即使负载很轻,客户端也可以选择减少请求。此选项通过引入少量人为延迟来实现这一点;因此,生产者将等待指定的延迟时间后再发送记录,以便能够发送其他记录,从而可以批量处理发送的内容。
此设置确定了批处理延迟的上限:无论此设置如何,一旦我们为分区积累了 batch.size 大小的记录,它们就会立即发送;但是,如果我们为该分区积累的字节数少于此值,我们将在等待新记录到达时“停留”指定的时间。其默认值为 0(即无延迟)。例如,将 linger.ms 降低到 3 会导致发送的请求减少,但在没有负载时提交的记录将延迟最多 3 毫秒。
COMPRESSION _TYPE_CONFIG: 生产者将对所有数据使用相同的压缩类型。None 是默认压缩类型(表示不压缩)。有效的压缩类型为 none、gzip、snappy、zstd 和 lz4。批处理的效率也会影响压缩率,因为压缩会使用整个数据批次(批处理越多,压缩效果越好)。
在Java(spring boot)中向生产者添加配置,
- Java
import java.io.*;
@Configuration class GFG {
@Bean(name = "dummyData") public KafkaProducer<String, DummyData> dummyDataKafkaProducer() { Map<String, Object> config = new HashMap<>(); config.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); config.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); config.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class); config.put(ProducerConfig.DELIVERY_TIMEOUT_MS_CONFIG, 600000);
// this configuration for compression config.put(ProducerConfig.BATCH_SIZE_CONFIG, 86016); config.put(ProducerConfig.LINGER_MS_CONFIG, 100); config.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, "snappy");
return new KafkaProducer<>(config, new StringSerializer(), new JsonSerializer<>()); }
} |
2. Broker 级 Kafka 压缩
如果目标主题的压缩配置设置为 compression.type=producer,代理会从客户端接收压缩的批处理并将其直接写入主题的日志文件,而无需重新压缩数据。默认情况下,代理配置中的 compression.type 设置为生产者。如果主题有自己的压缩选项(例如 gzip)并且值与生产者设置匹配,则消息批处理将以当前状态记录到日志文件中;否则,代理将解压缩消息并将其重新压缩为其预定格式。
Kafka 消息压缩
总结
当我们需要向 Kafka 发送大量数据时,消息压缩就派上用场了。网络调用将大幅减少,压缩消息的存储要求也将大大降低。