从此
文章
📄文章 #️⃣专题 🌐上网 📺 🛒 📱

为何要使用EventSourcing事件源?

🕗2023-06-04

Event Sourcing事件溯源,将事件建立为系统中唯一的事实来源。通过采用动态一致性边界DCB,eventSourcing提供了高度灵活的事件使用,允许随着时间的推移出现最佳的设计。

事件流系统
事件流系统通常使用发布-订阅消息传递模型将事件分发给多个消费者。事件流需要某种形式的事件持久性以确保软件组件之间的时间解耦。即使组件在发布事件时暂时不可用,它也可以在再次可用时赶上错过的事件。但是,事件流并不一定需要无限期地持久化事件。在许多情况下,事件仅保留必要的持续时间以确保它们传播到感兴趣的组件。

事件流应用程序通常根据存储在专用数据库中的当前状态来确定发布哪些事件。

事件溯源在这方面不同于事件流:

事件溯源涉及利用过去的事件来验证事件的后续发布,确保一致性。

此方法依赖于过去发布的事件来确定成功发布事件必须满足的一致性条件。一致性由事件存储保证,只有当一致性条件被验证时才允许事件发布。

本质上,事件溯源使用事件作为维护不变量完整性的手段,超出了事件流的范围。

事件持久化
无限期地持久化事件是一种自然的审计形式。此外,事件持久性允许存储可用于不同目的的几条附加信息,例如数据挖掘和分析。但是,请务必注意,随着事件数量不断增加,无限期保留事件可能会导致大量磁盘空间需求。

1、事件流
事件流非常适合异步通信。它使任何组件都可以发布事件,而不必担心这些事件可能触发的后果。这是一个非常强大的概念,因为它允许将流程分成许多小动作,将确定性部分(管理事件发布的业务规则)与非确定性部分(已发布事件的后果)隔离开来。

虽然事件流有助于重现生产问题,但它会使调试复杂化。当与事件的无限持久性相结合时,事件流允许事件重播并授权实施利用过去事件的新功能。但是,应用程序必须随着时间的推移支持所有先前发布的事件

2、事件溯源
事件溯源来自技术需要。使用事件流专用工具的要求带来了挑战:不可能在同一事务中发布事件和保存当前状态。

有两个资源不共享相同的事务范围: 



由于无法保证分布式事务性,当前数据结构和事件之间的一致性变得无法实现。

为了解决这个问题,事件溯源确保为两个目的使用单一资源。事件溯源使用事件存储作为提供当前状态所需的唯一资源,由过去的事件表示,并通过发布新事件来发展该状态。 事件存储通过在未能满足预期的一致性条件时拒绝追加来保证仅在与过去一致时才发布事件。 

事件溯源的批评者经常强调从过去的事件重建当前状态的复杂性
虽然这是事实,但动态一致性边界 (DCB) 的优点胜过缺点。

通过将数据的存储方式(事件)与用于验证不变量的结构分离,事件溯源提供了巨大的灵活性。通过采用 DCB,从过去的事件流中动态重建任何必要结构的能力将其从劣势转变为显着优势。

事件源简化了乐观锁的实现。
由于事件是不可改变的,因此只需验证是否有能够影响我的决定的新事件,有些事件在读取当前状态时被忽略了,因为它们是后来添加的。

动态一致性边界DCB

动态一致性边界代表一种特定于基于事件源的系统的乐观锁形式。

它背后的想法很简单。 

在使用事件溯源时,任何决策都可以由一个函数表示,该函数接收一个有序的事件流作为输入,并产生一个额外的有序事件流作为输出。
任何允许并发写入操作的系统都必须承认这样一种可能性,即在输入事件流的加载和输出事件流的追加之间,可能会发生另一个追加,这可能会使所做的决定无效。
为了保证决策的一致性,当且仅当附加时的输入事件流与加载时的输入事件流完全相同时,输出事件流必须被附加。

换句话说,没有发生任何相关的事情来影响决策

这就是为什么负责加载与做出正确决定决策有关的事件流的组件也要负责验证这个事件流在附加决定结果的时刻是否仍然是相同的。换句话说,它应该执行以下操作:



为了支持动态一致性边界的方法,事件存储应该提供以下能力:



事件存储的不可改变性使得有条件追加变得简单。
给定一个查询,只需验证最后一个事件是否匹配,就可以确定整个流是否匹配。  


总之,在回答为什么使用事件源的问题时,我想说:事件源将事件确立为系统内的单一事实来源;此外,通过采用DCBs,事件源提供了对事件的高度灵活使用,允许最佳设计随着时间的推移而出现。