0

例子

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

房屋在系统版本 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')

在不接受所有节点关闭的系统中,这通常是如何处理的?

4

1 回答 1

1

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

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

于 2013-02-08T17:14:02.373 回答