Architecture 使用微服务体系结构时如何保持数据库同步?

Architecture 使用微服务体系结构时如何保持数据库同步?,architecture,microservices,Architecture,Microservices,我将要学习微服务体系结构是如何工作的。到目前为止,我还不知道每个微服务都需要自己的数据库,这是有道理的 假设我们有一个客户微服务,负责创建客户并返回客户列表。当然,该服务将拥有自己的客户数据库 假设我们在这个服务上有很高的负载,所以我们选择扩展20倍 我们有20个微服务,每个都有自己的数据库,所有的服务都在负载平衡器后面 现在客户机想要创建客户机,负载平衡器将客户机请求发送到服务9/20,客户机就创建好了 在下一个请求中,同一客户希望确保客户已创建,并希望查看客户列表,在请求中,LB将其发送至s

我将要学习微服务体系结构是如何工作的。到目前为止,我还不知道每个微服务都需要自己的数据库,这是有道理的

假设我们有一个客户微服务,负责创建客户并返回客户列表。当然,该服务将拥有自己的客户数据库

假设我们在这个服务上有很高的负载,所以我们选择扩展20倍

我们有20个微服务,每个都有自己的数据库,所有的服务都在负载平衡器后面

现在客户机想要创建客户机,负载平衡器将客户机请求发送到服务9/20,客户机就创建好了

在下一个请求中,同一客户希望确保客户已创建,并希望查看客户列表,在请求中,LB将其发送至service 11/20

现在,我如何确保9/20服务将新创建的客户同步到11/20服务的db

在MSSQL中,有一些功能可以在初始提交之前保持数据库同步,首先将数据保存在所有其他数据库中,但从长远来看,这种方法会带来问题,因为服务越多,提交所需的时间就越长

每个微服务都需要自己的数据库

每个微服务单独的DB不是一个先决条件(实际上也不是一个要求)

您可以在同一个数据库上使用任意数量的微服务,但例如使用不同的模式

微服务的有界上下文应该是边界

假设我们在这个服务上有很高的负载,所以我们选择扩展20倍

扩展到同一微服务的(X)个实例并不意味着同一服务的每个实例都必须有一个单独的数据库

大多数数据库的设计都考虑了并发连接、用户和事务。单个数据库实例(具有一些乐观的并发性)可以优雅地处理数百(如果不是数千)个并发连接

如果您明确选择为同一服务的每个实例使用一个单独的DB,则必须同步这些数据库。而且,最有可能的是,数据一致性将因此受到影响

以下是一些建议:

  • 无论有多少实例在使用它,每个微服务(而不是每个实例)使用一个数据库。当您确信单个数据库不能处理负载时,只考虑每个实例的dB。

  • 使用数据库顶部的共享缓存层(可能是redis缓存)

  • 使用数据库集群来处理数据库的高负载/高可用性


这可以通过使用CQRS设计模式来实现,该模式通过遵循异步范式来分离实体的创建和查看


在创建时,我们将实体持久性推送到Kafka/RabbitMQ,并异步推送到数据库。可以在数据库上创建具体化视图,从而加快检索速度。

虽然可以将同一数据库用于多个服务,但应避免使用,因为这将在服务之间创建比预期更高的耦合。例如,数据库宕机将影响所有共享服务,但如果每个服务都有自己的服务,则仅影响单个服务

为了避免相互之间进行同步调用(例如使用REST)的“分布式整体”服务,您可以使用基于流的方法。每个服务在其数据发生更改时都会发布一个更改事件,其他服务可以订阅这些流。因此,他们可以对与其相关的数据更改做出反应,例如,通过在自己的数据库中存储本地版本的数据(以适合其需要的表示形式,例如,仅存储他们感兴趣的列)。这样,他们可以提供自己的功能,如果其他服务在一段时间内不可用的话。当然,这样的体系结构使用最终一致性的语义,但通常这在分布式系统中是不可避免的

设置此类数据流的一种方法是change data capture CDC,它将跟踪数据库日志文件(例如MySQL中的binlog),并为每次插入、更新和删除发布相应的事件。一个开源CDC工具是MySQL、Postgres、MongoDB以及Oracle和SQL Server的连接器。它可以与ApacheKafka一起用作流式主干或Java应用程序中的库,允许您只需一点代码即可将数据更改流式传输到其他流式层,如Pulsar或Kinesis。对更改事件使用持久性主题(例如Kafka)的一个很好的优点是,新服务可以出现并重新读取整个更改流(取决于主题的保留策略),或者只获取每个记录的当前状态以对其本地数据库进行初始种子


(免责声明:我是Debezium的负责人)

访问多个数据库只会将软件体系结构的一个问题更改为分布式协调的一个问题,后者是一个更加困难的问题

人们建议使用事件系统,这意味着每个单一服务现在都必须有自己的分布式数据协调解决方案,ACID不再适用。看看数据库环境,您会发现这不是一个容易的问题,也不是一个完全解决的问题。然后转到分布式协调事务

很多时候,您希望停机,而不是让N个数据库处于完全未知的不一致状态。此外,对启动时间的看法是误导性的,是的,您的服务启动了,但是如果它们对相同的数据或丢失的数据(丢失的事件)有不一致的看法,那么它们是否真的起作用?还是会产生不一致和错误的结果

要么您有两个完全不依赖于拥有相同数据的服务,要么您需要一个共享的一致数据层。但是N和d之间的复制