带有事件源的多个写边?

问题描述 投票:0回答:2

当使用带有聚合的事件源作为事务范围时,您显然更喜欢将聚合放在一台机器上。但是,如果您还想构建一个高度可用且可水平扩展的系统,您还想在不同数据库的许多机器上复制此状态。

如果在任何给定时刻只允许该网络中的一台机器上有一个写端,则其他机器可以是最终一致的读端。但为了最大限度地提高写入性能,我想同时允许多个写入面会更好。但是在这样的系统中如何处理一致性和共识?

当两台或多台机器想要同时更新公共但复制的状态时,我如何确保命令由所有写入端以相同的顺序处理,以便产生的事件相同并且具有相同的顺序? Lamport 时钟是解决方案的一部分吗?

domain-driven-design event-sourcing blockchain consensus
2个回答
1
投票

我在 Shuttle.Recall(无耻插件)ES 实现中处理这个问题的方式是在聚合 id 事件存储中的版本上构建一个唯一的聚集索引。通过这种方式,对同一个 AR 的多次写入永远不会重叠,并且两者之一将会“丢失”。当然,这仅适用于使用中央数据存储,但也许您的实现具有类似的可用机制。

没有限制可以同时写入事件存储的客户端数量。然而,投影处理必须是单个机器上每个命名投影的单个线程,因为事件排序非常敏感。好吧,我猜可以在不同的机器上处理不同的投影。


1
投票

但是为了最大限度地提高写入性能,我想最好允许 多个写入面同时。但是一致性和 在这样的系统中处理共识?

在事件源系统中,写端的一致性总是很强的。这是由聚合和

Event store
通过使用乐观锁定强制执行的:在并发写入的情况下(实际上事件仅附加到存储)整个命令被重试。这是可能的,因为聚合命令方法是纯(无副作用)方法。只要事件没有持续存在,就可以重试命令。

当两台或多台机器同时更新状态时(这 一个选择和坚持?)

两者。第一个(总是有第一个)命令生成持久保存到商店的事件。由于低级别并发异常,secons 命令失败。然后通过加载+应用所有以前的事件重试,包括第一个命令生成的事件。然后第二个命令生成附加事件,如果新状态不允许处理第二个命令,这些事件也会被持久化或抛出异常。

你必须注意到第二个命令至少执行了两次,但每次之前的事件(因此状态)都不同。

基础架构将聚合版本附加到每个聚合流。每个附加的事件都会增加这个版本。聚合 id 和版本有唯一约束。这可能是所有事件存储的实现方式。

当机器行为不当(无意或有意)并传播 网络其余部分的故障事件(如何检测?)

我不明白这是怎么发生的,但如果它正在发生,那么它真的取决于您对故障事件的理解。你可以有一些 Sagas/Process 经理来分析事件并触发一些发送给某种主管的电子邮件。

© www.soinside.com 2019 - 2024. All rights reserved.