如何处理去中心化事件源数据库中的共识?

How to handle consensus in a decentralized event sourced database?

假设我有 X 服务器的动态网络(不随时间固定),在仅附加数据库中具有所有事件的相同副本。现在我想支持在这 10 台服务器中的任何一台上创建新事件并让它们达成共识,复制事件并以完全相同的事件顺序产生所有结果。我知道这是一个常见问题,并且有一些算法应该可以处理这样的事情。但我没有完全理解它们,我有几个问题,特别是关于与事件溯源相关的共识。

我假设服务器永远无法完全确定它认为已达成共识的值真的是最终成为 "correct" 的值吗?我基于这样一个事实,即新服务器可以随时加入网络并使天平倾向于另一个值。这也可能会在很久以后发生。但是在这种情况下,服务器应该如何处理一个新的 "correct" 值呢?在事件溯源中,附加补偿事件以进行更正是正常的,但是这些补偿事件不应该也必须复制到所有服务器吗?确保所有服务器都具有完全相同的事件我的意思。

如果不添加补偿事件,而只是 "popping" 已经提交的事件,我想我们不必复制这些事件,但我们会 运行 到其他问题中。如果(错误地)提交的事件在事件总线上发送出去,以便其他服务可以对它们做出反应,我们不能只是从我们的事件数据库中弹出它们而不把事情搞砸。

还是在短时间内达成共识后真正承诺一个价值更好?然后冷眼对待所有new/late台服务器?无论如何都要让他们接受结果?如果新服务器连接到它自己的网络,该网络比第一个服务器更大,并且他们都就另一个值达成共识怎么办?

我不知道您对分布式系统的背景是什么,但是已经建立了共识算法(例如 Raft、Paxos、Viewstamped Replication 等),可以在不影响提交的情况下处理从集群中添加和删除服务器事件。

通常,您不会应用事件,直到它们被大多数人提交,特别是因为(如您所提到的)一些应用的事件将具有外部可见性(例如,您从 ATM 机中释放 500 美元)。因此,为了让服务器应用事件,它必须知道事件已经提交。此外,当服务器被添加到系统中时,它们必须与已经提交的事件保持同步,并且它们不能选择不同的值。如果他们可以选择不同的值,系统将不再提供安全性。我建议阅读 Raft 论文。 Raft 是一种可能适合您的共识算法,并且该算法不难理解。 Raft 专门处理添加和删除服务器(参见第 6 节)。您还可以使用 Raft 的实现。

还有其他算法支持弱一致性和undo操作,比如Bayou。您选择的算法最终取决于您的应用程序的需求。