带有事件源的 CQRS 看起来非常适合作为我们其中一个系统的架构,我们目前只担心一件小事:处理大量事件并因此处理大量事件存储。
我们当前的系统每天接收大约一百万个事件(尽管目前与事件源无关),如果我们要在更长的时间内存储它们,我们的事件存储可能会变得非常大,但如果我们转储/清除频繁地滚动快照,我们可能会失去事件溯源的一大优势:关于系统历史和重放的信息。
在 CQRS 架构中处理这个问题的常用方法是什么?有问题吗?我们是否只是在活动商店中投入更多的硬件,还是在架构设计层面我们可以做些什么?
带有事件源的 CQRS 看起来非常适合作为我们其中一个系统的架构,我们目前只担心一件小事:处理大量事件并因此处理大量事件存储。
我们当前的系统每天接收大约一百万个事件(尽管目前与事件源无关),如果我们要在更长的时间内存储它们,我们的事件存储可能会变得非常大,但如果我们转储/清除频繁地滚动快照,我们可能会失去事件溯源的一大优势:关于系统历史和重放的信息。
在 CQRS 架构中处理这个问题的常用方法是什么?有问题吗?我们是否只是在活动商店中投入更多的硬件,还是在架构设计层面我们可以做些什么?
我认为最常见的方法是使用快照和持久读取模型。也就是说,您实际上并不经常重播您的事件,除非您需要构建一个新的读取模型或更改现有模型的工作方式。通过存储域对象的快照,您可以避免重播长的事件流。
有人可能会争辩说,存储快照和持久读取模型与仅在没有事件源的情况下进行 CQRS 并没有太大不同。但是,如果您在读取模型中犯了错误,或者需要导出新信息,或者有其他严格的审计要求,那么旧事件就会存在。
在我们的应用程序中,我们有许多业务价值较低的事件,我们计划在执行期间大量清理事件,以便我们的事件日志保持较小。但我想对于某些对象,我们仍然会退回到快照和持久模型。
查看您的“活动流集”。是否存在具有生命周期的流,它们往往会出现,在相对较短的时间内发生变异,然后在达到最终状态时死亡?如果是这样,这些流可以转移到更便宜的存储(备份)。您需要它们的唯一原因是出于重播目的,因此您可能希望使它们仍然可访问(尽管响应速度较慢)或保留压缩副本以用于重播目的。在任何情况下,请询问是否有流可以移出事件存储或至少移出活动流集。
另一种选择是跨多个物理事件存储分区您的流。也许有一个可以使用的地理边界,或者也许有一些东西可以自然地划分它们(你所在的域通常会提供提示)。这是你需要反思优点和缺点的事情。
这种技术不限于事件溯源。它同样可以应用于基于状态的模型(毕竟它只是数据)。