Event sourcing

CloudEvent中的Event sourcing

备注:内容摘录自 https://cloudstate.io/docs/user/features/eventsourced.html

事件源是一种提供ACID语义的持久化方法,可跨实体进行水平扩展和故障隔离。

源于 Event sourcing 的实体不是保留实体的当前状态,而是保留导致实体达到其当前状态的所有事件。这些事件存储在日志中。当实体的当前状态加载到内存中时,将读取日志,并重播每个事件,以计算实体的当前状态。

在分布式系统中,Event sourcing 的最大优势之一是可以将实体的状态可靠地复制到其他服务和视图。与基于CRUD的实体不同,后者没有固有的方式来了解特定更新是否已在其他地方复制,事件源实体可以利用其事件持久化到日记这一事实,并在该日记中使用 offset 来跟踪系统的哪些部分复制了哪些事件。这是实现命令查询责任隔离( Command Query Responsibility Segregation / CQRS)模式所必需的基本构建块,因为它允许通过使用事件日志来使读取侧视图保持最新。

基于事件的实体还允许进行时间查询,其中可以在历史记录的任何点重新创建实体的状态。这对于审核目的很有用,因为事件日志可以用作审核日志,也可以用于调试目的。

一致性保证

基于Event sourcing的实体提供了强大的一致性保证。基于Event sourcing的实体在有状态服务部署中的每个节点上共享-在任何给定时间,每个实体都将恰好位于一个节点上。如果命令到达位于不同节点上的实体的特定节点,则该命令由代理转发到包含该特定实体的节点。该转发是透明完成的,用户功能不知道它的发生。

因为每个实体都恰好位于一个节点上,所以该节点可以按顺序处理每个实体的消息。因此,不存在与事件源实体相关的并发问题,每个实体一次只处理一个消息。

术语

Cloudstate在事件源方面使用以下术语:

  • 状态

    状态是当前设置的 event sourced 实体实例的值。它由 event sourced 实体保存在内存中。

  • 命令

    命令是一个消息,寻址到特定实体来执行特定操作。命令来自发送者,并且答复可以发送到发送者。命令可能与事件有所不同,因为命令是执行操作的请求-它指的是将来应该发生的事情。命令可能会失败。另一方面,事件指的是过去已经发生的事情。该事件是当前服务如何发现该事件的信息-我们无法更改该事件,因为该事件已经发生。但是,一个服务发出的事件可能被另一服务解释为命令。命令不持久,只有事件持久。

  • 命令处理程序

    一个命令处理程序是处理一个命令的代码。它可以使用当前状态来验证命令,并且可以发出事件作为其处理的一部分。命令处理程序不得直接更新实体的状态,而只能通过发出事件间接地更新实体的状态。如果命令处理程序确实更新了状态,则当钝化实体(从内存中删除)时,这些更新将丢失

  • 事件

    一个事件是一块得到持久数据的提供并且指示已经发生改变的实体。事件存储在日记中,并且每次由状态管理系统重新加载实体时都读取并重播事件。

  • 事件处理程序

    事件处理程序是被允许的唯一代码段更新该实体的状态。它接收事件,并根据事件更新状态。

  • 快照

    快照是实体的整个当前状态的记录,作为优化,它会定期保留(例如,每100个事件)。使用快照,当从日记中重新加载实体时,不需要重播整个日记,只需重播上次快照以来的更改即可。

  • 持续化ID

    持久化ID是持久时被预置到各实体ID的标识符。如果要在多个有状态服务之间共享数据库,则必须为每个实体选择唯一的持久性ID,这样它们的实体实例才不会发生冲突,这一点很重要。

个人看法:引入 eventing source 和 CQRS,复杂度大幅上升,cloudstate 的这种设计太重,落地会是很大的问题。