Sarama 库的一些默认行为在特定场景下不是最优。这里描述下。
默认刷新全部 topic 的 Metadata
如果初始化 client 时没有指定 config.Metadata.Full
为 False
,Sarama 默认会定时获取该集群所有 topic 的 Metadata。对于有非常多 topic(比如数千)的集群,Metadata 会占非常多的内存(实测 1000+ topic 消耗 30M 内存)。假如你的进程同时有多个 consumer group(比如数十个),每个 consumer group 的 client 都会刷新这份 30M 的 metadata,对 CPU 和内存的消费巨大。
因此,应该设置 config.Metadata.Full
为 False
。
在 Consumer 消费较慢时会断开订阅关系
有时可以看到 Sarama 打出的如下日志:
consumer/broker/3/ abandoned subscription to your_topic/0 because consuming was taking too long
这是因为 Sarama 认为 consumer 消费太慢,因此暂时断开与 broker 的订阅关系。Sarama 会在一段时间后重新订阅上。在一些实时系统中,这种行为可能会影响数据的处理时延。
Sarama 认为 consumer 消费太慢,这是几个因素共同决定的:
- Consumer 的缓冲区大小(
Consumer.ChannelBufferSize
选项,默认是 256) Consumer.MaxProcessingTime
,默认是 100ms
看这两个选项的文档可以理解 Sarama 的行为。
但这两个选项的默认值,在消费者是一个批量写入逻辑时,会有问题。比如消费者从 Kafka 读取数据,攒一批后再写入数据库;假如它攒消息的逻辑是收集至多 1000 条、间隔最多 1s 去做写入,那么当 topic 中数据量爆增时,会触发上述的断开订阅关系行为。
因此如果是批写的场景,consumer 缓冲区应该调到比一批写入数据的数量上限大(比如 2000),MaxProcessingTime
应该设置得比一次写入的耗时长。