【问题标题】:Kafka topic and multiple instances of a microserviceKafka 主题和微服务的多个实例
【发布时间】:2021-10-04 12:04:35
【问题描述】:

这更像是一个系统设计问题。

假设我有一个微服务架构,并且我有 X 个实例 Service B(用于对服务的 HTTP 请求进行负载平衡)。但是,Service B 也是某个 Kafka 主题的消费者。如何避免处理相同的消息X 次(X 是Service B 的实例数)?如果处理是幂等的,at least once 可能会很好。不需要是exactly once,但不能是X times

服务 A 可以是订单服务。它会生成有关用户向 Orders topic 下订单的消息。

服务 B 可以是支付服务。它使用来自 Orders 主题 的消息来向用户收费。

为订单付款可能是幂等操作。但是,如果我有 10 个支付服务实例,我不想浪费 CPU 和 IO 做 10 次。

即使分区是答案,如果我们拥有的特定微服务实例比分区多怎么办?

【问题讨论】:

    标签: apache-kafka microservices messaging autoscaling idempotent


    【解决方案1】:

    根据问题,

    即使您有多个服务实例,您也不必担心对同一消息的重新处理。因为 Kafka 在消费者偏移量上工作,所以如果您曾经阅读过该消息,我们会提交该消息的偏移量,以便该消息对该消费者(组)不可用。

    举个例子,

    Order 服务发布关于 Order 主题的消息和订阅它的支付服务。我们有 10 个支付服务实例。在这种情况下,让我们考虑由支付服务实例 1 消费的消息 1(如果您没有明确定义,它属于默认消费者组)。消费消息 1 后,支付服务实例 1 提交该消息的偏移量(在消费者组级别),它将被视为消息已成功处理。所以支付服务实例 2/任何其他实例只会选择偏移为未提交的消息。

    根据@Madhu 的回答,它是为了更快和并行处理消息。如果您有 10 个支付服务实例并且想要快速访问和处理消息,那么您可以在消费者组下添加更多消费者(但需要考虑订单主题的分区数,因为如果订单主题有 4 个分区并且我们定义了 5 个消费者,那么除非任何其他消费者宕机,否则 1 个消费者始终处于空闲状态。

    【讨论】:

      【解决方案2】:

      Kafka 消费群体

      当您拥有x 服务实例并且您希望该服务仅使用一次消息时,这是 Kafka 的消费者组概念负责处理的事情。

      本质上,您需要为您的服务实例指定一个通用 kafka 消费者组 ID,然后 kafka 会负责将主题的分区分配给您服务的不同消费者实例,这样就不会有任何消息被您的服务消耗两次。

      在您正在使用的 kafka 消费者库中的 kafka 消费者配置中,会有一个消费者组 ID 的配置。您只需要确保为您的一组服务实例分配了与该配置相同的消费者组 ID 值。

      举例说明

      如果您的服务 B10 实例,则您为所有 10 个实例指定一个通用 kafka 消费者组 ID,例如 serviceBConsumerGroup。当一个具有 10 个分区的 kafka 主题开始消费时,kafka 负责将该主题的分区分配给消费者组serviceBConsumerGroup 的所有实例。所以本质上它会将每个分区分配给每个实例(当有 10 个服务实例和 10 个主题分区时)。如果服务有 5 个实例,kafka 主题有 10 个分区,Kafka 会为每个实例分配 2 个分区供消费。

      一些关于 Kafka 消费者群体的参考资料:

      【讨论】:

      • 当你有 x 个服务实例并且你希望消息只被服务消费一次时,这是 Kafka 的消费者组概念需要处理的事情。-- 这不是真的。即使您有 x 个实例并且只有一个消费者,也不会再次处理任何消息,因为它适用于消费者偏移量。处理消息后,消费者提交该消息的偏移量,以便该消息不会再次被处理。问题是关于消息的再处理而不是消息的并行处理。
      • @Vaibs Kafka 消费者始终处理消费者偏移量,即跟踪哪些消息已被消费者组消费。如果一个服务有 x 个实例,并且它们都有唯一的消费者组,那么一个主题的消息可以被服务消费 x 次。 OP 的问题是“我怎样才能避免处理 X 次相同的消息”,这就是将相同的消费者组分配给所有实例所达到的目的。
      • 我认为这与您所说的完全相反。如果我有 10 个消费者属于一个唯一的单个消费者组并且消息被再次处理,那么消费者组的用途是什么。AFAIK 每个消费者组都有唯一的 ID。当我们添加并行性或其他一些消费者想要对该主题数据进行一些其他操作时,消费者组就会出现。例如消费者A根据订单数据进行计算,消费者B根据订单数据发送通知请查看此博客dzone.com/articles/…..
      • @Vaibs 你误解了我的意思,当我说“一个服务的 x 个实例,所有这些实例都有唯一的消费者组”时,这意味着消费者组对于每个实例都是唯一的。这意味着,每个实例的消费者群体都是不同的。然后消息将被消费 x 次。您将 unique 这个词误解为 common。他们是对立的。
      • 如果您有任何困惑,请检查我添加到我的答案中的参考资料。
      猜你喜欢
      • 2021-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-25
      • 2019-11-01
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多