事件溯源-《复杂软件设计之道:领域驱动设计全面解析与实战》笔记 – 6

文章目录

  • 1. 关于事件溯源
  • 2. 基于事件溯源的聚合根设计
    • 2.1. 用事件替代状态
    • 2.2. 用活动替代聚合根
  • 3. 事件溯源优点
    • 3.1. 替代分布式事务
    • 3.2. 事件日志的顺序性
  • 4. 总结

1. 关于事件溯源

MartinFowler在2005年的博客中提及了“EventSourcing”这个词语,他将事件描述为一个应用的一系列状态改变,这一系列事件能够捕获用来重建当前状态的一切事实真相。他认为事件是不可变的,事件日志是一种只会不断追加(appendonly)的存储。事件从来不会被删除,这意味着事件可以被重播。

举例说明:支付宝的账户余额与进出明细存在一种关系:进出明细应该是导致账户余额变动的原因,其中存储了构成账户余额的各个事件,影响当前账户余额的是这些事件的总和。

事件溯源的基本思想是确保在事件对象中捕获应用程序状态的每个更改,并且将这些事件对象按照它们发生的顺序存储(事件明细),这些存储的信息称为事件日志,它可作为直接存储状态本身的替代。不仅可以通过事件日志查询这些事件,还可以使用事件日志重建过去的状态,并作为自动调整状态以应对追溯更改的基础

只存储事件而不存储状态,这样不至于在同时发生大量并发访问时,对数据库中的状态进行竞争式的修改,从而巧妙回避了通过加锁防止并发修改又导致的性能问题

如果将事件集合中的运行看成电影一样的流动,那么状态如同在某个时刻对流动的事件实现的快照,代表那个时刻系统的状态。当前状态始终可以从事件中派生。这个过程被称为投影(Projection)

投射成的状态结果可以有几种保存方式:内存、关系数据库、NoSQL和文件系统,操作方式可以是同步或异步,投射的过程中可能存在性能问题,可以通过缓存设计或其他提前计算并存储状态的方式解决。

事件溯源的事件不一定是领域事件,追溯事件是来自聚合发出的用于重建状态的领域事件,而领域事件是更广泛的一种事件,可以用于在不同有界上下文之间实现通信。

传统以数据库E-R图为核心的架构只保留和维护对象的当前状态,而事件溯源维护状态的所有更改操作:

Untitled

3. 事件溯源优点

  • 一次写入多读(WORM,Write Once Read Many)数据存储等技术可与事件溯源互补使用,WORM存储能在硬件级别防止数据更改,并且只允许附加新数据。
  • 在硬件级别就防止数据更改,并且只允许附加新数据
  • 调试那些已经捕获的事件可用于进一步了解系统为什么会达到当前状态,哪些事件造成了当前状态。事件溯源在可跟踪性和调试能力方面体现了优势。
  • 事件溯源还有可伸缩性的优势,只追加的事件日志是同步复制状态的唯一方法。相比状态字段锁而言,由于复制不可变的事件日志几乎不需要用锁,在CQRS中,复制事件日志比直接复制状态更易于扩展。
  • 信息价值也是应用事件溯源的一个动机,检查事件日志可以重建或查询系统的所有过去状态。这可以为系统提供很大的价值,特别是当分析交互作用时。在这样的系统中,通常不知道将来要做什么样的分析。例如一个在线商店,商家老板希望列出顾客放入购物车或取走的所有商品列表,这样能够比较商品的受欢迎程度,使用事件溯源架构可以很容易遍历这个购物车事件集合并罗列出来。

3.1. 替代分布式事务

采取事件溯源时,应用不是直接将记录写入两个存储系统,而是将更新事件追加到事件日志中,数据库和搜索引擎库各自订阅此日志,并按照它们在日志中出现的顺序将更新写入自己的存储中。通过日志对更新进行排序,数据库和搜索索引以相同的顺序应用相同的写入集,使它们彼此保持一致。

3.2. 事件日志的顺序性

如果事件日志不是集中存放,而是每个参与者都有一份完整的日志(例如在分布式环境中,事件日志是复制给多个节点之间存放的),那么如果需要对事件日志进行追加,也必须满足只能由一个节点实现追加的条件,多个节点基于共识(Paxos或Raft)算法选出主节点进行事件追加

4. 总结

系统记录的是事件,而不是状态,但是事件的发现有赖于状态的发现。状态机存在于每个系统中,对状态变化的敏感有助于发现导致状态变化的原因。

现代软件架构或已走上了这样的设计思路:

  • 在接受前端请求向后端写入数据的方向上,采取事件溯源或区块链技术
  • 在从后端向前端返回查询数据的方向上,则采取人工智能和大数据分析,将更符合用户体验的数据定制化推向用户。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年2月15日
下一篇 2022年2月15日

相关推荐