首页 文章

Kafka 消费者再 balancer 算法

提问于
浏览
15

有人可以告诉我Kafka消费者的再 balancer 算法是什么吗?我想了解分区计数和消费者线程如何影响这一点 .

谢谢,

2 回答

  • 28

    好的,目前有2种重新 balancer 算法 - RangeRoundRobin . 它们也称为分区分配策略 .

    为简单起见假设我们有一个主题 T1 有10个分区,我们也有2个不同配置的消费者(为了更清楚的例子) - C1num.streams 设置为 1C2num.streams 设置为 2 .

    以下是 Range 策略的工作原理:

    范围以字典顺序以数字顺序和消费者线程布局可用分区 . 所以在我们的例子中,分区的顺序是 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ,消费者线程的顺序是 C1-0, C2-0, C2-1 . 然后将分区数除以使用者线程数,以确定每个使用者线程应拥有多少分区 . 在我们的例子中,它不会平分,所以线程 C1-0 将获得一个额外的分区 . 最终的分区分配如下所示:

    C1-0 获取分区 0, 1, 2, 3
    C2-0 获取分区 4, 5, 6
    C2-1 获取分区 7, 8, 9

    如果有11个分区,这些消费者的分区分配会有所改变:

    C1-0 会得到分区 0, 1, 2, 3
    C2-0 会得到分区 4, 5, 6, 7
    C2-1 会得到分区 8, 9, 10

    而已 .

    相同的配置不适用于 RoundRobin 策略,因为它需要在订阅此主题的所有消费者中使用 num.streams ,因此我们假设两个消费者现在都将 num.streams 设置为2 . 与 Range 策略相比,一个主要的区别是,您无法预测重新 balancer 之前的分配 . 以下是 RoundRobin 策略的工作原理:

    首先,在实际分配之前必须满足2个条件:

    a)每个主题在消费者实例中具有相同数量的流(这就是为什么我在上面提到每个消费者的不同线程数不起作用的原因)
    b)订阅主题集对于组内的每个消费者实例都是相同的(我们这里有一个主题,所以现在不是问题) .

    当验证这两个条件时, topic-partition 对按哈希码排序,以减少将一个主题的所有分区分配给一个使用者的可能性(如果要使用多个主题) .

    最后,所有 topic-partition 对都以循环方式分配给可用的消费者线程 . 例如,如果我们的主题分区最终将按如下方式排序: 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 那么分配将如下所示:

    T1-5 转到 C1-0
    T1-3 转到 C1-1
    T1-0 转到 C2-0
    T1-8 转到 C2-1
    此时不再有剩余的消费者线程,但仍有更多的主题分区,因此对消费者线程的迭代重新开始:
    T1-2 转到 C1-0
    T1-1 转到 C1-1
    T1-4 转到 C2-0
    T1-7 转到 C2-1
    然后再次:
    T1-6 转到 C1-0
    T1-9 转到 C1-1

    此时,所有主题分区都被分配,每个消费者线程每个分区的分区数量几乎相等 .

    希望这可以帮助 .

  • 1

    您可以阅读有关消费者注册算法和消费者重新 balancer 算法的Kafka文档http://kafka.apache.org/documentation/#impl_brokerregistration

    正如它所说,每个消费者在重新 balancer 期间都会做以下事情:

    1. For each topic T that C<sub>i</sub> subscribes to
    2.   let P<sub>T</sub> be all partitions producing topic T
    3.   let C<sub>G</sub> be all consumers in the same group as C<sub>i</sub> that consume topic T
    4.   sort P<sub>T</sub> (so partitions on the same broker are clustered together)
    5.   sort C<sub>G</sub>
    6.   let i be the index position of C<sub>i</sub> in C<sub>G</sub> and let N = size(P<sub>T</sub>)/size(C<sub>G</sub>)
    7.   assign partitions from i*N to (i+1)*N - 1 to consumer C<sub>i</sub>
    8.   remove current entries owned by C<sub>i</sub> from the partition owner registry
    9.   add newly assigned partitions to the partition owner registry
        (we may need to re-try this until the original partition owner releases its ownership)
    

    并注意到:

    如果消费者多于分区,则某些消费者根本不会获得任何数据 . 在重新 balancer 期间,我们尝试以减少每个消费者必须连接的代理节点数量的方式为消费者分配分区 .

相关问题