来自给定分区的消息是否可以在多个线程上划分?假设我有一个单独的分区和一百个进程,每个进程有一百个线程 - 来自我的单个分区的消息是否只被赋予这10000个线程中的一个?
答案 0 :(得分:4)
多个线程不能使用相同的分区,除非这些线程位于不同的使用者组中。尽管您有很多闲置消费者,但只有一个线程会消耗来自单个分区的消息。
分区数是Kafka中的并行度的单位。要使多个使用者使用相同的分区,您必须将主题的分区数增加到您想要实现的并行性,或者将每个单独的线程放入单独的使用者组中,但我认为后者是不可取的。
答案 1 :(得分:2)
如果您有多个消费者在同一个消费者群体下使用同一主题,那么主题中的消息将分配给这些消费者。换句话说,每个消费者将得到消息的非重叠子集。以下几行取自Kafka FAQ页面
我应该为消费者选择多个组ID还是一个?
如果所有消费者使用相同的组ID,则主题中的消息将分布在这些消费者中。换句话说,每个消费者将获得消息的非重叠子集。 在同一组中拥有更多消费者可提高并行度和消费总体吞吐量 。请参阅下一个问题,以选择使用者实例的数量。另一方面,如果每个消费者都在自己的组中,则每个消费者将获得所有消息的完整副本。
为什么消费者群体中的某些消费者从未收到任何消息? 目前,主题分区是我们在同一个使用者组中的消费者之间分发消息的最小单元。因此,如果消费者数量大于Kafka集群中的分区总数(跨所有代理),则某些消费者将永远不会获得任何数据。解决方案是增加代理上的分区数
答案 2 :(得分:0)
在极端情况下没有。
Kafka高级消费者可以确保一条消息只消耗一次。并确保一个分区最多只能由一个线程使用。
因为,kafka高级消费者中存在本地队列。 消费者认为,如果您从本地队列中查询了一条消息,那么您已经消费了该消息。
让我们讲一个故事:
线程1使用分区0。
线程1轮询了一条消息m0。消息m1,m2 ...已经在本地队列中。
重新平衡,kafka将清除本地队列并重新注册。
线程2现在消耗分区0,但线程1仍然消耗m0。
线程2可以轮询m1,m2 ......现在。
此时您可以看到两个线程正在使用相同的分区。
答案 3 :(得分:0)
而不是使用线程更好地增加消费者和分区以获得更好的吞吐量和更好的控制