Kafka: Library: Sarama: Pitfalls

 18th April 2022 at 6:17pm

Sarama 库的一些默认行为在特定场景下不是最优。这里描述下。

默认刷新全部 topic 的 Metadata

如果初始化 client 时没有指定 config.Metadata.FullFalse,Sarama 默认会定时获取该集群所有 topic 的 Metadata。对于有非常多 topic(比如数千)的集群,Metadata 会占非常多的内存(实测 1000+ topic 消耗 30M 内存)。假如你的进程同时有多个 consumer group(比如数十个),每个 consumer group 的 client 都会刷新这份 30M 的 metadata,对 CPU 和内存的消费巨大。

因此,应该设置 config.Metadata.FullFalse

在 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 应该设置得比一次写入的耗时长。