kafka 如何决定哪个消费者读取单个消费者组内的消息?

时间:2021-01-09 09:12:10

标签: apache-kafka kafka-consumer-api

我想知道是否有任何逻辑可以确定哪个消费者读取同一消费者组中的消息。我有一个主题和一个消费者群体。但是,我有一个或多个消费者,因为在生产环境中部署了一个消费者,当我在本地运行我的应用程序时,会创建另一个订阅同一主题的消费者(这是一个测试项目,所以它不是真正的生产,我不担心数据丢失)。我注意到有趣的是本地消费者总是消费任何给定的消息。所以看起来后来创建的消费者优先。

是否可以将 kafka 配置为较早创建的使用者优先读取?

我的设置包括 3 个经纪人和 1 个消费者组 ID。此外,此 property auto.offset.reset 设置为 earliest(将其更改为 latest 并不能解决问题)。我正在将这个 Go library 用于 kafka。这是我的设置代码:

import (
    "log"
    "github.com/confluentinc/confluent-kafka-go/kafka"
)

func getConfig() *kafka.ConfigMap {
    return &kafka.ConfigMap{
        "metadata.broker.list": conf.KafkaBrokers,
        "security.protocol":    "SASL_SSL",
        "sasl.mechanisms":      "SCRAM-SHA-256",
        "sasl.username":        conf.KafkaUsername,
        "sasl.password":        conf.KafkaPassword,
        "group.id":             conf.KafkaGroupID,
        "default.topic.config": kafka.ConfigMap{"auto.offset.reset": "earliest"},
        //"debug":                           "generic,broker,security",
    }
}

1 个答案:

答案 0 :(得分:2)

在一个消费者组内,每个分区由一个消费者消费。当消费者加入组时,其中一个计算由每个消费者将处理的分区列表组成的分配。

在您的客户端中,这可以通过 partition.assignment.strategy 进行配置。这默认为 range,它遵循 Apache Kafka 的 RangeAssignor 的实现。

引用 Javadoc:

<块引用>

范围分配器在每个主题的基础上工作。对于每个主题,我们按数字顺序排列可用分区,按字典顺序排列消费者。然后我们将分区数除以消费者总数,以确定分配给每个消费者的分区数。如果不是均分,那么前几个消费者会有一个额外的分区。

例如,假设有两个消费者 C0 和 C1,两个主题 t0 ​​和 t1,每个主题有 3 个分区,从而得到分区 t0p0、t0p1、t0p2、t1p0、t1p1 和 t1p2。

任务将是:

C0: [t0p0, t0p1, t1p0, t1p1]
C1: [t0p2, t1p2]

消费者按他们的会员 ID 排序,会员 ID 是在代理端生成的。它基于消费者 client.id 和随机 UUID。

在实践中,每个分区分配给哪个消费者并不重要,因此我不会过多关注该部分。相反,了解分区的分配方式并确定最适合您的用例的策略非常重要。

为了完整性,confluent-kafka-go 还支持其他策略,例如:roundrobincooperative-sticky