【问题标题】:Spring boot kafka: Microservice multi instances, concurrency and partitionsSpring Boot kafka:微服务多实例、并发和分区
【发布时间】:2021-07-28 20:32:12
【问题描述】:

我有一个关于在 kafka 中发布和读取消息的方式的问题,用于微服务架构,具有用于写入和读取的相同微服务的多个实例。 我的主要问题是发布和读取的微服务配置了自动缩放,但默认实例数为 1。

关键是我有一个实体,我们称之为“事件”,存储在 DDBB 中,每个实体在 DDBB 中都有自己的 ID。当在特定实体中执行某些特定命令时(比如说 entityID = ajsha87),它必须发布一条消息,供消费者阅读。如果同一实体的每条消息都写在不同的分区中并同时使用(并发问题)我会有很多问题。

我的问题是,例如,我是否可以根据 entityID 设置该特定实体的所有事件将在哪些分区中发布。对于具有不同 ID 的另一个实体,我不关心分区,但同一实体的消息必须始终发布在同一个分区中,以避免消费者读取消息 (1) 之后发布的消息 (2)。 有什么机制可以做到这一点,或者每次我保存实体时,我都会在 DDBB 中随机存储将发布其消息的分区 ID?

消费者也是如此。只有一个消费者可以同时读取一个分区,因为如果不是,一个消费者编号 1 可以从与实体 (ID=78198) 关联的分区 (1) 中读取消息 (1),然后另一个消费者可以从中读取消息 (2)分区(1)与同一实体相关,并处理第一个之前的消息2。

根据微服务自动伸缩,每个实例只订阅一个分区有什么机制吗?

另一种选择是动态地为每个新发布者实例分配一个分区,但我不知道如何动态地配置它以根据微服务实例设置不同的分区 ID

顺便说一下我用的是spring boot

感谢您的回答和建议,如果我的英语不够好,请见谅。

【问题讨论】:

    标签: spring-boot apache-kafka concurrency microservices kafka-partition


    【解决方案1】:

    如果您在生产者配置中使用Hash Partitioner 作为分区器(这是许多库中的默认分区器),并且对同一个实体使用相同的密钥(比如说 entityID = ajsha87),kafka 会设法使用相同的密钥发送所有消息到同一个分区。

    如果您使用组消费者,则一个消费者实例负责一个分区,并且发布到该分区的所有消息仅由该实例消费。如果在升级时有重新平衡,则可以更改实例。但仍然会从一个消费者实例中读取同一分区中的消息。

    【讨论】:

    • 我理解了关于消费者的部分,正如我所看到的,它很简单,只需为所有消费者设置相同的 group-id 就可以确保只有一个实例读取特定分区。但是仍然不了解产生消息的部分,因为我不知道kafka如何记住因为实体ajsha87的第一个消息发布是在分区一中发布的,因此具有此哈希的所有消息必须始终进入分区一。这在创建更多具有不同哈希的实体时也有效?
    • 如果提供了key,partitioner会用murmur2算法对key进行hash,除以partition的个数。结果是相同的键总是分配给相同的分区。如果未提供密钥,则行为取决于 Confluent 平台版本 如果您使用此 HashBased 分区程序,则具有相同密钥的每条消息都会进入同一分区。更多信息请参考https://docs.confluent.io/platform/current/clients/producer.html#concepts
    • 好的,非常感谢您为我解惑!
    猜你喜欢
    • 1970-01-01
    • 2021-10-04
    • 2019-02-01
    • 2018-01-27
    • 2019-02-20
    • 2021-09-28
    • 1970-01-01
    • 2023-02-10
    • 2018-03-28
    相关资源
    最近更新 更多