在将数据保存到数据库中时,一般也会往缓存或搜索引擎里保存一份。这里的挑战在于如何在绕开分布式事务和双重写入的情况下保持数据的同步。一种方式是借助变更数据捕获(Change Data Capture,CDC)工具捕获数据变更,并将其发布到数据库中。在柏林举行的 MicroXchg 大会上,Gunnar Morling 介绍了Debezium,一种借助 Kafka 将数据变更发布成事件流的 CDC 实现。
Morling 是红帽公司的一名工程师,他分享的 Debezium 是一款开源的、基于 Kafka 的 CDC 工具,它会读取数据库事务日志,并将其发布成事件流。其他应用程序按照正确的顺序异步消费这些事件,然后根据实际需求更新自己的数据存储。
数据库的事务日志文件是一种仅追加模式的日志文件,用于进行回滚和复制。在 Morling 看来,这种日志是理想的数据库数据变更来源,因为它们包含了所有的数据变更以及变更发生的顺序。所有数据库都提供了用于读取这种日志文件的 API,所以 Debezium 内置几种数据库连接器。Debezium 会在输出端生成通用的 Kafka 抽象表示。
CDC 除了可以用来更新缓存、服务和搜索引擎,Morling 还介绍了其他几种用例,包括:
数据复制,通常用来将数据复制到其他类型的数据库或数据仓库中。
审计。因为保留了数据历史,在使用元数据填充数据后,可以实现数据变更审计。
在基于微服务的系统中,其中服务通常需要来自其他服务的数据。不过 Morling 表示,最好要避免在服务间共享数据库,而使用 REST 调用会增加服务间的耦合性。在这种情况下,我们可以使用 CDC。我们将数据变更创建为事件流,其他服务可以订阅这些流,并更新它们的本地数据库。因为事件管道是异步的,在发生网络问题时,允许服务滞后处理变更,但最终会追赶上来——系统是最终一致性的。
Morling 指出,暴露内部结构其实是有问题的(之前的例子),但这个问题可以通过”发件箱“(outbox)模式来解决。我们会使用单独的事件表,而不是直接捕获由业务领域所使用的表数据变更。当领域发生变更时,需要在同一事务中向事件表中发布一条数据。这个事件表就是发件箱,其中包含了需要发送到其他系统的事件。
在开始采用微服务架构之前,一般会有一个需要拆解成微服务的单体。Morling 表示,为了验证拆解出来的服务是否正确,可以使用 CDC。将写入请求保持在单体上,然后捕获变更,然后用它们来验证新服务的行为是否正确。
Morling 在另一篇博文中详细介绍了发件箱模式。Martin Kleppmann 在之前的一篇博文中介绍了如何使用日志来构建健壮的基础设施以及为什么说双重写入是一种很糟糕的做法。
更多有关大会演讲的内容将在未来几个月陆续提供。
查看英文原文:Creating Events from Databases Using Change Data Capture: Gunnar Morling at MicroXchg Berlin
评论