转载 | 什么是Event Sourcing?
Event Sourcing
传统的数据存储通常关注实体的当前状态。例如,在电子商务系统中,你可能会存储客户订单的当前状态:商品、数量、收货地址等。而事件溯源采用了不同的方法。它不是直接存储当前状态,而是存储导致该状态的事件。每个事件都代表了过去发生的一个事实。可以把它看作银行对账单中详细的交易日志。这些事件是不可变的,存储在仅追加的事件存储中。核心思想是应用程序的状态可以通过按事件发生的顺序重放这些事件来推导,就像你可以通过从头重放所有交易来得到当前的银行余额一样。这使得事件溯源对于需要高度可审计性和可追踪性的应用特别有用。
How Event Sourcing Works
在事件溯源系统中,应用状态的每一次变化都会被捕捉为一个事件对象。这些事件随后被存储在事件存储中,事件存储是一种为处理事件数据而优化的数据库。以下是事件溯源的分步骤工作原理:
- 事件创建:当用户执行某个操作(例如,下订单)时,应用会创建一个描述该操作的事件对象。
- 事件存储:该事件被存储在事件存储中。该存储是仅追加的,意味着事件只能被添加,永远不会被修改或删除。
- 状态重建:为了确定实体(例如,一个订单)的当前状态,应用会从事件存储中重放所有与该实体相关的事件。
想象一个电子商务应用。与其存储购物车的当前状态(商品、数量等),我们存储像“ItemAddedToCart”(商品加入购物车)、“ItemRemovedFromCart”(商品从购物车移除)、“QuantityUpdated”(数量更新)等事件。每个事件代表购物车的一个具体变化。购物车的当前状态可以通过按顺序重放这些事件随时重建。
Rebuilding State in Event Sourcing
从事件中重建状态涉及从事件存储中读取与某个实体相关的所有事件,并按顺序应用这些事件以重建当前状态。这就像模拟所有发生过的变化来构建当前状态。例如,考虑一个电子商务应用,其中订单经历了“已创建”、“已付款”和“已发货”等不同状态。为了确定订单的当前状态,你需要:
- 从事件存储中检索与订单相关的所有事件。
- 初始化一个空的订单对象。
- 按存储的顺序将每个事件应用到订单对象上。
经过这个过程后,订单对象将反映订单的当前状态。
Use of Snapshots in Rebuilding State
随着事件数量的增加,重放整个事件流以重建状态可能会变得缓慢且低效。这时,快照就派上用场了。快照是实体在特定时间点的保存状态。应用程序不必从头重放所有事件,而是可以加载最新的快照,然后只重放快照之后发生的事件。
Pros and Cons
优点:
- 可审计性:事件溯源提供了完整的变更历史,使得审计和追踪实体状态随时间变化变得容易。
- 调试:重放事件的能力使得通过重现实体在任意时间点的精确状态来调试问题变得更加简单。
- 灵活性:由于状态是从事件派生的,因此可以轻松添加新功能,或在不影响历史数据的情况下更改现有功能。
缺点:
- 复杂性:事件溯源增加了应用的复杂性。你必须围绕事件设计系统,实现状态重建,并管理快照。
- 存储需求:存储所有事件可能导致大量存储需求,尤其是对于运行时间长且事件众多的系统。
- 数据隐私:存储所有事件可能引发隐私问题,因为历史数据可能包含必须谨慎管理的敏感信息。