【发布时间】:2020-01-26 19:15:47
【问题描述】:
我了解微服务架构建议每个服务都应该有自己的私有数据库。但是当这样一个服务被扩展时,是每个服务实例一个db还是所有服务实例共享一个db?
【问题讨论】:
-
这是个好问题。如果数据在服务之间相互依赖,我建议不要尝试水平扩展有状态服务。如果水平扩展意味着能够对数据进行分区,使得没有两个服务必须竞争相同的数据,那么您可以做到。
标签: microservices
我了解微服务架构建议每个服务都应该有自己的私有数据库。但是当这样一个服务被扩展时,是每个服务实例一个db还是所有服务实例共享一个db?
【问题讨论】:
标签: microservices
确实是个好问题。我会这样回答:“每个微服务(不是实例)至少有一个数据库”
一个问题是数据库本身的可扩展性,即服务实例能否超出数据库的规模?
如果是这样,您可以选择例如内存数据库或微服务的边车。数据库将是短暂的,您需要在 pod/容器(重新)启动后填充它。所以状态并没有真正存在于数据库中。 Apache Kafka 是一个适合这一点的工具,因为它允许您在服务启动后填充数据库,并提供工具来同步所有当前运行和未来实例的状态。但是使用 Kafka 成功实现事件溯源并非易事,但您可以得出根本不需要数据库的结论。
所以问题仍然存在,服务实例真的可以超出数据库的规模吗? 答案往往是“不”。
因此,通过为每个微服务(物理上或逻辑上)拥有一个数据库实例,已经在“松散耦合和内聚行为”方面为您提供了很多好处,因为您不共享数据库。
另一个问题是微服务版本之间的数据库更改中断。如果出现问题,您可能会发现自己无法回滚。临时数据库可以以兼容的方式自行同步。
有人说他们会在微服务的整个生命周期内更改数据库技术,我从来没有必要这样做,但内存/sidecar 方法非常适合这里。
【讨论】:
您的第一句话可能会误导某些人:“每个服务都应该有自己的私有数据库。”
您的架构应该小心在多个服务之间共享一组表 - 频繁共享会导致共享架构依赖,这会产生紧密耦合,使得在不更新许多服务的情况下很难更新架构同时共享该架构。
但是,共享单个数据库实例(或数据库集群)并不意味着您的服务正在访问数据库中的相同表或什至相同的架构。如果他们没有访问相同的表,他们就没有耦合。 (依赖同一个数据库实例与依赖同一个网络没有任何耦合。不要将耦合与共享基础架构混淆。)
通常,同一服务的多个实例共享同一个数据库。在我看来,这本身并没有错,但有一些事情需要注意。如果您走这条路,则在更改数据模式时需要非常小心。由于该服务的多个版本可能在更新期间同时访问数据,因此任何模式更改都需要至少与任何两个相邻版本兼容。如果您添加列或表,那很好。旧版本不会尝试使用它,所以不会有问题。 (还要注意,旧版本也不会填充它。)删除列或表完全是另一个问题,要进行这种重大更改,您可能需要分几个较小的步骤来确保旧版本服务的版本没有损坏。可以做到,只是难度更大。
【讨论】:
我假设您与一个微服务的所有实例共享一个数据库。因此,同一微服务的每个实例都可以立即获得一个更新。您可以为每个微服务实例使用一个数据库实例,以避免数据库成为单点故障。但是您必须使每个数据库保持同步,这对于数据库和应用程序来说似乎是不必要的过载。我假设数据库能够使一组数据库实例保持同步(每次插入、更新、删除都会正确传播)。
【讨论】: