微服务数据复制模式

Posted

技术标签:

【中文标题】微服务数据复制模式【英文标题】:Microservice data replication patterns 【发布时间】:2019-08-02 10:09:30 【问题描述】:

在一个微服务架构中,我们通常有两种方式让 2 个微服务进行通信。假设服务 A 需要从服务 B 获取信息。第一个选项是远程调用,通常通过 HTTPS 同步,因此服务 A 查询服务 B 托管的 API。

第二种选择是采用事件驱动的架构,服务B的状态可以被服务A以异步的方式发布和消费。使用此模型,服务 A 可以使用来自服务 B 事件的信息更新其自己的数据库,并且所有查询都在此数据库中本地进行。这种方法的优点是可以更好地解耦微服务,从开发到运营。但它有一些与数据复制相关的缺点。

第一个是磁盘空间的高消耗,因为相同的数据可以驻留在需要它的微服务的数据库中。但在我看来,第二个是最糟糕的:如果服务 B 无法按需要尽快处理其订阅,或者在服务 B 创建它的同时它不能用于服务 A,则数据可能会变得陈旧,鉴于模型的最终一致性。

假设我们使用 Kafka 作为事件中心,其主题配置为使用 7 天的数据保留期。服务 A 在服务 B 发布其状态时保持同步。两周后,部署了一个新的服务 C,并且需要使用服务 B 所拥有的所有信息来丰富它的数据库。由于最旧的事件已经消失,我们只能从 Kafka 主题中获取部分信息。我的问题是我们可以使用哪些模式来丰富这个微服务的数据库(除了要求服务 B 将其所有当前状态重新发布到事件中心)。

【问题讨论】:

【参考方案1】:

有两种选择:

    您可以为单个主题启用 Kafka 的日志压缩。这将保留给定密钥的最新值,丢弃旧更新。这可以节省空间,并且在给定的保留期内比正常模式保存更多的数据

    假设你每天对服务B DB进行备份,在引入新服务C时,你需要首先从B的最新备份中创建C的初始状态,然后重播Kafka主题来自表示备份后数据的特定偏移 id 的事件。

【讨论】:

【参考方案2】:

您的担忧是正确的,但同时微服务方法是给予和接受。您会以每个服务的单个数据库为代价获得松散耦合。微服务架构没有正确的答案,实际上取决于您要实现的目标。

根据 CAP 定理,您必须在一致性和可用性之间做出妥协,在大多数情况下,我们会采用最终一致性。如果您的服务 A 与 B 不一致,那么它最终会是一致的,这是以可用性为代价的权衡。

关于微服务的另一件事是,您只保留来自其他服务的数据的引用,并且可能来自其他服务的实际数据非常有限,但绝对不会太多。而且只有在复制数据使您的服务独立和自治的情况下,如果即使在复制数据之后您也无法实现其中任何一项,那也没有意义。例如您的运输服务将有完整的订单转换历史,但您的预订服务只有最新的订单状态(例如在运输中、在上等)。用户去预订,你显示订单的当前状态。但是,如果用户单击详细信息,您将获得来自运输微服务的所有订单转换历史记录。现在在某些时候,您的运输服务出现故障,并且您的用户会检查您的状态,即使您无法显示详细信息,因为订单状态已在预订服务中复制。

关于后期加入系统的新服务,事件溯源是您用于此类场景的模式。它的模式很复杂,但它会将您新添加的服务带到您希望它们处于的状态。您基本上将所有事件保存在事件存储中并重放它们以获取系统的当前状态并使用这些事件预填充服务 C 数据库。

【讨论】:

以上是关于微服务数据复制模式的主要内容,如果未能解决你的问题,请参考以下文章

微服务架构:聊天服务或数据复制

数据复制或 API 网关聚合:使用微服务选择哪一个?

知道微服务架构下如何做数据复制吗?

缓存加速——Redis服务之主从复制哨兵模式群集模式

Hazelcast 集群:序列化和复制问题

Redis主从复制和哨兵模式