从事件溯源/CQRS 的角度来看:假设我有一个包含 2 个实例的消费者组,它订阅了一个主题。在启动/订阅时,每个实例都会处理其在事件流中的份额,并构建数据的本地视图。
当外部请求带有更新数据的命令时,该请求将如何路由到组中的正确实例?如果数据按实体 ID 进行分区,奇数 ID 发给消费者 1,偶数 ID 发给消费者 2,这将如何传达给消费者?或者,就此而言,任何反向代理或服务网格负责将传入请求发送到正确的实例?
而当消费者群体由于消费者的增加或减少而重新平衡时会发生什么?这是否以某种方式自动传达了路由机制?
当消费者都从给定主题的新事件集重建他们的本地模型时,服务是否存在差距?
这似乎适用于事物的命令和查询方面,如果它们都在具有分区数据的多个实例之间划分...
我的想法是否正确?
谢谢
答案 0 :(得分:1)
Kafka 分区非常适合按它们影响的实体对命令和事件流进行分片,但不适用于以其他方式(例如路由请求)使用此分片。
我推荐的对实体状态进行分片的广泛技术是不依赖于 Kafka 分区(仅使用主题分区来确保实体的命令/事件的排序,即通过将所有命令/事件用于一个实体给定实体在一个分区中),而是使用外部的东西来协调这些分片(候选人将包括 zookeeper/etcd/consul 中的租约或来自 akka(JVM)或 akka.net 或 cloudstate/akka serverless(更多多语言)的集群分片) .从那里,您可以采取两种广泛的方法:
(如果用于状态和处理的实体分片数量恰好等于 Kafka 分区的数量,则最适用)将消费者组协议的一部分移动到您的应用程序中,并让拥有特定分片的实例使用特定分区
让从 Kafka 摄取的实例解析实体的分片以及哪个实例拥有该分片,然后将请求路由到该实例。相同的模式还允许任何实例处理诸如对实体的 HTTP 请求之类的事情。通过这样做,您将以有状态方式实现的服务呈现给诸如服务网格/容器调度器/负载平衡器之类的事物,因为它是更无状态的服务。