Kafka 的消费者线程数应该等于主题分区数

Mat*_*sen 5 apache-kafka kafka-consumer-api

假设您确定要为您的应用程序使用 8 个消费者线程。

如果 Kafka 主题设置为具有 8 个分区和 16 个分区,处理过程会有什么差异吗?

在第一种情况下,每个线程被分配到具有两倍数据的单个分区,而在第二种情况下,每个线程被分配到两个分区,每个分区具有一半的数据。在我看来,这两种设置没有区别。

mju*_*rez 4

我相信,在消费者方面,如果您的线程不受 CPU 限制(并且网络未满负荷),则可能会有所不同。假设 Kafka 代理上存在无限数据,或者有一个滞后的消费者,由于第二个示例中每个线程都从两个分区进行消费,因此与每个线程仅分配一个分区相比,Kafka 代理能够发送更多的数据。Kafka 对每次提取可检索的最大字节数(在配置中)有限制replica.fetch.max.bytes,因此,如果您将分区增加 2 倍,则可以增加容量(假设数据可用)。

当配置正确并假设理想条件时,Kafka将从页面缓存中提供数据,因此它可以将数据下传给消费者,90%的情况下,瓶颈将是消费者端的分区/可用CPU数量。一般来说,你拥有的分区越多,你从 Kafka 消费的速度就越快,直到你的消费者的 CPU 或带宽受到限制,此时你拥有更多或更少的分区并不重要,因为你正在消费数据无论如何,尽可能快。

另一件需要考虑的事情是,可能会有更多的消费者提交被发送回代理,因为现在有更多的分区,这意味着集群中会有一些额外的开销/串扰。它可能不是提交量的 2 倍,但可能高于第一个场景提交量的 1 倍。

要记住的一件重要事情是,只要有可能,就在消费者的线程外进行实际的消息处理。也就是说,不要从 Kafka 消费/轮询的同一线程上处理入站消息。一开始它可能会起作用,但是如果您的处理时间更长、存在延迟、入站侧的数量大幅增加等,您将开始遇到问题。只要有可能,请将入站消息放入队列中,然后让另一个队列处理线程担心处理/解析它们。

最后,您不想将其发挥到极致,如果不需要,请配置 1000 个分区。每个分区都需要提交、zookeeper znode、消费者重新平衡时间、启动时间等方面的开销。因此,我建议对不同的场景进行基准测试,看看什么最适合您。一般来说,每个消费者线程 2-4 个分区在过去对我来说效果都很好,即使消息负载非常高(每秒 50K+ 消息的主题,每个 ~1KB)。