如何在分布式事件源系统中进行版本逻辑

时间:2013-02-08 15:20:06

标签: domain-driven-design versioning distributed-computing cqrs event-sourcing

示例

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

在系统版本1中构建1年的房屋,但在版本2中需要两倍的时间。这是逻辑而非结构的变化。< / p>

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

问题

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

从合并分布式节点合并事件日志时会产生问题。事件版本相互渗透,使得在重放期间无法简单地从版本1升级到2。 E.g:

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')

如果在不接受所有节点的系统中通常如何处理?

1 个答案:

答案 0 :(得分:1)

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

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