Domain driven design 使用事件源的多个写方?

Domain driven design 使用事件源的多个写方?,domain-driven-design,event-sourcing,blockchain,consensus,Domain Driven Design,Event Sourcing,Blockchain,Consensus,当使用带有聚合的事件源作为事务范围时,您显然更喜欢将该聚合放在一台机器上。但是,如果您还想构建一个高可用性和水平可伸缩的系统,那么您还需要在不同数据库的许多机器上复制这种状态 如果在任何给定时刻只允许网络中的一台机器上有一个写端,那么其他机器最终可以是一致的读端。但是为了最大限度地提高写性能,我想最好同时允许多个写端。但在这样一个系统中,如何处理一致性和共识 当两台或多台计算机希望同时更新公共但已复制的状态时,如何确保所有写入方以相同的顺序处理命令,以便生成的事件相同且顺序相同?兰波特时钟是解决

当使用带有聚合的事件源作为事务范围时,您显然更喜欢将该聚合放在一台机器上。但是,如果您还想构建一个高可用性和水平可伸缩的系统,那么您还需要在不同数据库的许多机器上复制这种状态

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

当两台或多台计算机希望同时更新公共但已复制的状态时,如何确保所有写入方以相同的顺序处理命令,以便生成的事件相同且顺序相同?兰波特时钟是解决方案的一部分吗

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

在事件源系统中,写入端的一致性始终很强。这是由聚合和
事件存储
通过使用乐观锁定实现的:在并发写入的情况下(事实上,事件仅附加到存储),将重试hole命令。这是可能的,因为聚合命令方法是纯(无副作用)方法。只要事件没有持久化,就可以重试该命令

当两台或多台计算机同时更新状态时(其中 一个选择和坚持?)

两者都有。第一个(总是有第一个)命令生成持久化到存储的事件。由于低级并发异常,secons命令失败。然后通过加载并应用所有以前的事件(包括第一个命令生成的事件)重试。然后,如果新状态不允许处理第二个命令,则第二个命令生成也被持久化的传统事件或引发异常

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

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

当机器行为不当(不知不觉或故意)并传播时 向网络其余部分发送错误事件(如何检测?)


我不知道这是怎么发生的,但如果真的发生了,那就取决于你对错误事件的理解了。您可以使用一些传奇/流程管理器来分析事件并触发发送给某种主管的电子邮件。

我在穿梭机中处理这一问题的方法。Recall(无耻插件)ES实现是在事件存储中的聚合id和版本上构建唯一的聚集索引。这样,同一AR上的多个写操作就永远不会重叠,两个写操作中的一个将“丢失”。当然,这只适用于使用中央数据存储,但您的实现可能有类似的机制可用


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

谢谢你的回答。我看到当只有一个写端时可以使用乐观锁。但如果在不同的机器上有多个写端(没有一个公共数据库),他们就必须在处理什么命令上达成一致。乐观锁可以在一台具有并发写操作的机器上工作,但在一个扩展系统中如何处理并发写操作?@AndreasZita没有公共数据库,我认为这是不可能的。但是,使用公共数据库可以通过
聚合ID
使用分片。通过这种方式,您可以最小化并发写入的可能性。