【发布时间】:2021-04-06 23:07:12
【问题描述】:
我正在使用 Kafka 进行事件溯源,并且我对使用 Kafka 实现 sagas 很感兴趣。
关于如何做到这一点的任何最佳做法?提到的指挥官模式here 似乎接近我正在尝试构建的架构,但演示文稿中的任何地方都没有提到 sagas。
【问题讨论】:
标签: apache-kafka event-sourcing saga
我正在使用 Kafka 进行事件溯源,并且我对使用 Kafka 实现 sagas 很感兴趣。
关于如何做到这一点的任何最佳做法?提到的指挥官模式here 似乎接近我正在尝试构建的架构,但演示文稿中的任何地方都没有提到 sagas。
【问题讨论】:
标签: apache-kafka event-sourcing saga
今年 DDD eXchange 的这次演讲是我在事件驱动/CQRS 系统中遇到的流程管理器/Saga 模式的最佳资源: https://skillsmatter.com/skillscasts/9853-long-running-processes-in-ddd (需要注册免费账号才能查看)
那里显示的演示位于 github 上:https://github.com/flowing/flowing-retail
我试了一下,我很喜欢。我确实建议先观看视频以做好准备。
虽然显示的方法与消息总线无关,但该演示使用 Kafka 作为流程管理器来向其他有界上下文发送命令并侦听事件。它不使用 Kafka Streams,但我不明白为什么它不能插入到 Kafka Streams 拓扑中并成为更广泛架构的一部分,就像您引用的 Commander 演示文稿中描述的那样。
我希望根据我们自己的需要对此进行进一步调查,因此请随时在 Kafka 用户邮件列表上发起一个线程,这是就此类模式进行协作的好地方。
希望有所帮助:-)
【讨论】:
我想在这里添加一些关于 sagas 和 Kafka 的内容。
总的来说,Kafka 与普通队列略有不同。它在缩放方面特别好。这实际上会导致一些并发症。
实现扩展的方法之一,Kafka 使用数据流的分区。数据放置在分区中,可以按照自己的速率使用,独立于同一主题的其他分区。以下是有关它的一些信息:how-choose-number-topics-partitions-kafka-cluster。我会回来解释为什么这很重要。
在 Kafka 中确保顺序的最常用方法是:
在这两种情况下,您按时间顺序排列的消息都需要流经同一主题。
另外,正如@pranjal thakur 指出的那样,请确保将传递方式设置为“恰好一次”,这会影响性能,但可以确保您不会多次收到消息。
现在,需要注意的是:更改分区数量时,分区上的消息分布(使用密钥时)也会更改。
在正常情况下,这很容易处理。但是,如果您遇到高流量情况,则向不同数量的分区迁移可能会导致在某个时刻在多个分区上处理 saga-“流”,并且此时无法保证顺序。
这是否会成为您的方案中的问题取决于您。
您可以提出以下问题来确定这是否适用于您的系统:
如果您正在考虑根据步骤(例如状态机)设置 saga,我会要求您重新考虑一下您的设计。
我举个例子:
让我们考虑一个预订酒店房间的流程:
简单来说,它可能包含以下步骤:
现在,如果您的 saga 无法在预订尚未到来的情况下处理付款,那么您将依赖于事件的顺序。
在这种情况下,您应该问自己:什么时候会中断?
如果你断定你想避免时间依赖;考虑一个没有 saga 的系统,或者一个不依赖于事件顺序的 saga - 即:接受所有消息,即使过程中还没有轮到他们。
一些例子:
请注意,在这样的设置中,每个动作都有一个已实施的补偿动作(回滚动作),这一点更为重要。
我知道这通常很难实现;但是,如果你从小处着手,你可能会开始喜欢它:-)
【讨论】: