【问题标题】:How to migrate to Event-Sourcing?如何迁移到事件溯源?
【发布时间】:2021-04-23 12:45:02
【问题描述】:
我们正在从传统的单体应用程序迁移到微服务架构。我们使用 CQRS 和事件源模式和消息代理(rabbitmq)作为通信机制。现在我们面临着如何将旧数据库转换为新架构以及如何使用事件溯源的挑战?假设旧数据库没有事件,我们可以在不创建事件的情况下进行数据转换吗?我们在事件溯源模式中的旧数据库数据的起点是什么?
【问题讨论】:
标签:
microservices
domain-driven-design
cqrs
event-sourcing
【解决方案1】:
您有一个事件存储,它是事件的数据库。您可以创建旧数据库所需的事件数据并插入到事件存储中。之后,进行事件重放以创建读取模型。
【解决方案2】:
通过在this post 上引用@alexey-zimarev 的答案,在事件源数据库中包含开始事件是必不可少的。如果不重播其事件,则无法配置事件来源聚合。因此,您需要将旧快照映射到相关聚合的单个域事件。
无论如何,考虑一下 Martin Fowler 的 event souring definition:
事件溯源的基本思想是确保每个
应用程序状态的变化被捕获在事件对象中,
并且这些事件对象本身存储在序列中
它们被应用的生命周期与应用状态相同
自己。
因此,在不提取和存储域事件的情况下将旧快照迁移到新快照不是一个合适的解决方案。它会将您的事件源项目转变为不被视为设计和开发范式的半事件源项目。
【解决方案3】:
要记住的重要一点是,许多数据库内部都有事件源:每次写入都会写入日志,并且该日志用于更新表、复制等,之后日志会被截断。这相当于事件溯源,其中包含大量快照,而保留的事件和旧快照很少。
在这些数据库中(包括 Postgres、MySQL、Oracle、SQL Server、Cassandra、CosmosDB 等,我从经验中知道的都是这样做的),有一种称为变更数据捕获的技术,它本质上是利用日志和向数据库公开一个更改流,可以将其视为来自数据库的事件(或扩展为命令:“一个服务的事件是另一个服务的命令”)。 Debezium 可用于将 CDC 记录写入 Kafka;对于 RabbitMQ,您可能需要自己滚动一些东西,在这种情况下,您需要熟悉 CDC 在数据库中的公开方式。
即使数据库不支持 CDC,如果数据不是那么大,您通常可以通过定期转储其数据将其转换为 ersatz 事件流(如果记录带有时间戳,如果数据的移动速度特别慢)并实施一项服务来跟踪更改的内容:这不会告诉您已消除的更改,但通常总比没有好。如果您需要“创世”事件以确保您的初始状态与您迁移到事件溯源或 CDC 时保持一致,则也可能需要这种类型的转储。
与完整的事件溯源相比,这一系列广泛的技术存在局限性:具体化已更改的内容不如具体化已更改的内容及其更改的原因有价值。但它可能是迁移到事件溯源的一个有用的中间地带。