Domain driven design 如何在分布式事件源系统中对逻辑进行版本化

Domain driven design 如何在分布式事件源系统中对逻辑进行版本化,domain-driven-design,versioning,distributed-computing,cqrs,event-sourcing,Domain Driven Design,Versioning,Distributed Computing,Cqrs,Event Sourcing,示例 我的分布式事件源系统模拟一段时间内正在建造和购买的房屋。为简单起见,我们将使用年份作为分布式时钟值(暂时忘记向量时钟) 在系统版本1中建造房屋需要1年时间,但在版本2中需要两倍的时间。这是逻辑上的变化,而不是结构上的变化 为应对此更改,版本1在重建状态/快照时还必须重播版本1中记录的事件。当达到日志的版本2时,应用程序将切换到逻辑的版本2并继续重放剩余事件。将生成有效的快照 问题 我的分布式系统中的节点将在不同的时间更新到版本2,从而创建一个窗口,使多个版本同时运行。我目前的理解是,这个窗

示例

我的分布式事件源系统模拟一段时间内正在建造和购买的房屋。为简单起见,我们将使用年份作为分布式时钟值(暂时忘记向量时钟)

在系统版本1中建造房屋需要1年时间,但在版本2中需要两倍的时间。这是逻辑上的变化,而不是结构上的变化

为应对此更改,版本1在重建状态/快照时还必须重播版本1中记录的事件。当达到日志的版本2时,应用程序将切换到逻辑的版本2并继续重放剩余事件。将生成有效的快照

问题

我的分布式系统中的节点将在不同的时间更新到版本2,从而创建一个窗口,使多个版本同时运行。我目前的理解是,这个窗口只能通过功能切换等技术来减少,但不能完全删除(除非为了升级而牺牲整个系统的可用性)

这会在合并来自分布式节点的事件日志时产生问题。事件版本相互渗透,使得在重播期间无法简单地从版本1升级到版本2。例如:

Node    Clock   Event

... pre-merge ...

A       2000    HouseBuildStarted('Alpha')   
A       2001    HousePurchased('Alpha')    <- 'HouseBuilt' event is implicit (inferred through logic).
A       2002    NodeUpgradedTo('V2')
B       2002    HouseBuildStarted('Bravo')
B       2003    HousePurchased('Bravo')
B       2004    NodeUpgradedTo('V2')

... post-merge ...

A       2000    HouseBuildStarted('Alpha')
A       2001    HousePurchased('Alpha')
B       2002    HouseBuildStarted('Bravo')
A       2002    NodeUpgradedTo('V2')        
B       2003    HousePurchased('Bravo')    <- 'Bravo' does not exist yet (1 year early)
B       2004    NodeUpgradedTo('V2')
节点时钟事件
... 预合并。。。
2000年的房屋建筑开工(“阿尔法”)

升级逻辑和分发升级的问题是不同的。如果您需要升级事件流(例如,“内部构建事件是隐式的”),那么您应该这样做。您的读取模型必须通过重新播放事件流来重建,并使用执行升级的逻辑。这在概念上与升级程序时修补数据库没有什么不同。现在需要根据更新的表示重新考虑有关持久化数据的事实(可能必须替换默认值,忽略过时的事件等)

如何确定哪个节点运行哪个版本的代码是一个单独的问题。如果您有无停机升级策略,您通常会做什么?有些客户使用旧版本,有些客户使用新版本?同样的事情也可能发生,在旧的读模型在线时构建新的读模型,在部署新的读模型时为旧的聚合和应用程序服务,等等