Kafka 高级消费者:分区可以有多个线程消费吗?

Kafka high-level consumer: Can partitions have multiple threads consuming it?

来自给定分区的消息能否在多个线程上划分?假设我有一个分区和一百个进程,每个进程有一百个线程 - 来自我的单个分区的消息是否只会提供给这 10000 个线程中的一个?

多个线程不能使用同一个分区,除非这些线程在不同的消费者组中。尽管您有很多空闲消费者,但只有一个线程会使用来自单个分区的消息。

分区数是Kafka中并行的单位。要让多个消费者消费同一个分区,你必须增加主题的分区数,直到你想要达到的并行度,或者将每个单独的线程放入单独的消费者组,但我认为后者是不可取的。

如果您有多个消费者从同一消费者组下的同一主题消费,那么一个主题中的消息将分发给这些消费者。换句话说,每个消费者将获得消息的一个非重叠子集。以下几行摘自Kafka FAQ页面

Should I choose multiple group ids or a single one for the consumers?
If all consumers use the same group id, messages in a topic are distributed among those consumers. In other words, each consumer will get a non-overlapping subset of the messages. Having more consumers in the same group increases the degree of parallelism and the overall throughput of consumption. See the next question for the choice of the number of consumer instances. On the other hand, if each consumer is in its own group, each consumer will get a full copy of all messages.

Why some of the consumers in a consumer group never receive any message? Currently, a topic partition is the smallest unit that we distribute messages among consumers in the same consumer group. So, if the number of consumers is larger than the total number of partitions in a Kafka cluster (across all brokers), some consumers will never get any data. The solution is to increase the number of partitions on the broker

极端情况下不会。

Kafka high-level consumer可以保证一条消息只消费once.And保证一个partition最多只被一个线程消费

因为,kafka high-level consumer中有一个local queue。 消费者认为如果你从本地队列中轮询了一条消息,你就消费了这条消息。

所以让我们讲一个故事:

  1. 线程 1 消耗分区 0。

  2. 线程 1 轮询了一条消息 m0。消息m1,m2...已在本地队列中

  3. Rebalanced,kafka会清空本地队列,重新注册。

  4. 线程 2 现在消耗分区 0,但是线程 1 仍在消耗 m0。

  5. 线程 2 现在可以轮询 m1、m2...。

可以看到此时有两个线程正在使用同一个分区。

与其使用线程,不如增加消费者和分区以获得更好的吞吐量和更好的控制