kafka消费分区的分配策略

在 Kafka 内部存在两种默认的分区分配策略:Range 和 RoundRobin。当以下事件发生时,Kafka 将会进行一次分区分配:

  1. 同一个 Consumer Group 内新增消费者
  2. 消费者离开当前所属的Consumer Group,包括shuts down 或 crashes
  3. 订阅的主题新增分区

将分区的所有权从一个消费者移到另一个消费者称为重新平衡(rebalance),如何rebalance就涉及到下面提到的分区分配策略。下面我们将详细介绍 Kafka 内置的两种分区分配策略。本文假设我们有个名为 T1 的主题,其包含了10个分区,然后我们有两个消费者(C1,C2)来消费这10个分区里面的数据。

  1. Range strategy

Range策略是对每个主题而言的,首先对同一个主题里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序。在我们的例子里面,排完序的分区将会是0, 1, 2, 3, 4, 5, 6, 7, 8, 9;消费者排完序将会是C1, C2。然后将partitions的个数除于消费者的总数来决定每个消费者消费几个分区。如果除不尽,那么前面几个消费者线程将会多消费一个分区。

在我们的例子里面,我们有10个分区,2个消费者, 10 / 2 = 5,那么消费者 C1和消费者C2 将会消费同样多的分区,所以最后分区分配的结果看起来是这样的:

C1 将消费 0, 1, 2, 3, 4 分区

C2 将消费 5, 6, 7, 8, 9 分区

假如我们有11个分区,那么最后分区分配的结果看起来是这样的:

C1 将消费 0, 1, 2, 3, 4, 5 分区

C2 将消费 6, 7, 8, 9, 10分区

假如我们有2个主题(T1和T2),分别有11个分区,那么最后分区分配的结果看起来是这样的:

C1 将消费 T1主题的 0, 1, 2, 3, 4, 5 分区以及 T2主题的 0, 1, 2, 3, 4, 5分区

C2 将消费 T1主题的 6, 7, 8, 9, 10 分区以及 T2主题的 5, 6, 7, 8, 9, 10分区

可以看出,C1 消费者比C2消费者多消费了2个分区,这就是Range strategy的一个很明显的弊端。

  1. RoundRobin strategy

使用RoundRobin策略有两个前提条件必须满足:

  1. 同一个Consumer Group里面的所有消费者的num.streams必须相等;
  2. 每个消费者订阅的主题必须相同。

所以这里假设前面提到的2个消费者的num.streams = 2。RoundRobin策略的工作原理:将所有主题的分区组成 TopicAndPartition 列表,然后对 TopicAndPartition 列表按照 hashCode 进行排序,这里文字可能说不清,看下面的代码应该会明白:

val allTopicPartitions = ctx.partitionsForTopic.flatMap { case(topic, partitions) =>

  info("Consumer %s rebalancing the following partitions for topic %s: %s"

       .format(ctx.consumerId, topic, partitions))

  partitions.map(partition => {

     TopicAndPartition(topic, partition)

  })

}.toSeq.sortWith((topicPartition1, topicPartition2) => {

  /*

   * Randomize the order by taking the hashcode to reduce the likelihood of all partitions of a given topic ending

   * up on one consumer (if it has a high enough stream count).

   */

  topicPartition1.toString.hashCode < topicPartition2.toString.hashCode

})

最后按照round-robin风格将分区分别分配给不同的消费者线程。

在我们的例子里面,假如按照 hashCode 排序完的topic-partitions组依次为T1-5, T1-3, T1-0, T1-8, T1-2, T1-1, T1-4, T1-7, T1-6, T1-9,我们的消费者线程排序为C1-0, C1-1, C2-0, C2-1,最后分区分配的结果为:

C1-0 将消费 T1-5, T1-2, T1-6 分区;

C1-1 将消费 T1-3, T1-1, T1-9 分区;

C2-0 将消费 T1-0, T1-4 分区;

C2-1 将消费 T1-8, T1-7 分区;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值