我知道CQRS
可以使用或不使用事件溯源
来实现,但反过来行不行?没有CQRS
的事件溯源
是否有意义?如果有的话,应该如何实现?
我知道CQRS
可以使用或不使用事件溯源
来实现,但反过来行不行?没有CQRS
的事件溯源
是否有意义?如果有的话,应该如何实现?
没错,确实如此。
基本上,事件溯源的整个思想就是存储导致当前状态的更改,而不是存储当前状态。这样,使用事件溯源,您自动拥有历史记录,并且可以在数据上运行时间序列分析,并尝试从过去中学习。
是否使用CQRS是完全不同的故事:CQRS是关于将应用程序的写入与读取分离。
就像您可以在没有事件溯源的情况下使用CQRS一样,您也可以在没有CQRS的情况下使用事件溯源。两者互相独立,只是偶然很适合彼此。
我还没有见过使用ES而不使用CQRS的情况,因为这只有在您不需要跨多个实体进行任何查询/分析能力时才会发生。99%的情况下,这是一个要求;)
如果您想要跨多个实体进行查询,则一定需要类似于CQRS的东西,因为您将应用一种不同的查询数据方式,而不是使用事件源。 (除非您每次查询都想重新播放所有事件..)如何实现CQRS部分并不是固定不变的。它只是描述了读取和写入是以不同方式处理的两个独立问题。
因此,总体而言:不,这没有任何意义。
没有使用CQRS的事件溯源有意义吗?
是的,从某种意义上说,CQRS和事件溯源是正交的问题。
就像罐子上写的那样-你有一个模型来管理历史记录,既可以响应命令对历史记录进行更新,也可以根据历史记录构建查询的响应。
class BankAccount {
final History<Transactions> transactions;
void deposit(Money money) {...}
Money computeInterestAccruedSince(Date lastReview) { ... }
}
是的,事件溯源可以在不使用CQRS的情况下使用(正如现有的答案已经指出的那样),但当达到一定的复杂程度时,实现写操作(事件、日志等)与读操作(投影、视图等)的分离似乎是自然而然的需求。
偶然间看到了这篇文章The Log: What every software engineer should know about real-time data's unifying abstraction,虽然它是关于事件驱动的分布式系统,但人们很容易找到其中描述的概念与CQRS + 事件溯源之间的相似之处。这是一篇长而深入的文章,但值得一读。
引用来自“日志在系统架构中的位置”部分最相关的内容:
这是如何工作的。系统分为两个逻辑部分:日志和服务层。日志按顺序记录状态变化。服务节点存储用于查询的索引(例如,键值存储可能有类似B树或SSTable的结构,搜索系统可能有倒排索引)。