单一数据库 vs 多个数据库 - 微服务架构

36
我计划使用微服务架构来构建一个项目。我很好奇在数据库方面哪种设计更好?
1. 像给出的图片一样,为每个服务保留一个单独的数据库。

enter image description here

多个应用指向一个数据库。
如果我为每个服务保留一个单独的数据库,我们如何决定在哪里保存映射表呢?
例如,我们有一个名为“Customers”的服务(与数据库1通信的独立项目)和一个名为“Products”的服务(与数据库2通信的独立项目),我应该在哪里存储客户和产品的映射(客户购买的产品)?
从长远来看,如果我需要在多个表上进行连接(由于第1点中提到的架构原因,这些表位于不同的数据库中),那么报告该如何处理?
2个回答

38
如果您的数据有很强的关联性,并且对数据一致性和服务可用性有强烈要求,那么可以使用一个单一的共享数据库,并由不同的微服务拥有表。但是这种做法有利也有弊。
优点: 可靠性: - 您可以使用标准DB工具对整个系统进行完全一致的增量备份,而不会出现停机。 - 在事件驱动架构的情况下,您可以将事件存储在数据中。如果您将事件存储在数据库中,即使丢失broker也可以在没有数据损失的情况下运行。 - 完全约束和正确的数据关系。
维护: - 您不必编写网络接口从另一个服务提取数据,但如果您希望分离级别,也可以这样做! - 无数据重复和过期状态。
功能: - 可以执行复杂的查询,速度非常快! - 事务并不那么困难。(仍然需要重试)
缺点: 可靠性: - 另一个单点故障(简单情况下)。您可以使用复制设置进行高可用性,但需要OPS资源。
维护: - 模式更改(迁移)应该非常小心地进行(如外部API更改),即使实施了单个写入者原则,因为读取时模式不匹配也是永久性错误。对于大型项目,很难跟踪哪些表更改会受到影响。

纪律:

  • 只有表的所有者才能执行写操作。
  • 您仍需要努力将数据解耦以降低事务冲突的概率。

性能:

  • 在存储容量和性能方面很难进行扩展。几乎每个成熟的数据库都有聚集解决方案,但如上所述,它需要大量的运维资源。

厌恶:

  • 当你说你设计了微服务来使用单一数据库时,每个人都会无缘无故地讨厌你。忍耐它。

其他想法:

就我个人经验而言,如果您不是 Netflix 并且您的应用程序不能容忍任何形式的数据丢失,则单一数据库是一个不错的选择。

  1. “共享数据库”实际上被描述为 “架构模式”,具有其自身的优缺点。那么为什么要给它贴上“反对”的标签呢?
  2. 这篇这篇文章从相反的观点讨论了共享数据库模式。从我的角度来看,这完全是有道理的。
  • 这份文档介绍了BAC定理。它基本意思是,如果你使用多个数据存储,就不能同时拥有完整的正常运行时间和一致的备份。

  • 2
    很好的回答。microservices.io确实认为共享数据库是一种反模式。在该网站上搜索“anti”以查找“每个服务的数据库页面”。您会发现在“相关模式”下的最后一个要点链接到共享数据库页面,并将其标记为“共享数据库反模式”。 - James
    2
    此外,正如@V. Mokrecov所指出的那样,微服务架构专家Chris Richardson在共享数据库页面的评论中表示,这是一种反模式。 - James

    12
    第二种方法是微服务架构中的"共享数据库"反模式
    在微服务架构中,最好使用每个服务一个数据库的模式
    这些方法的优缺点也在页面末尾的链接中介绍。
    针对您关于如何存储客户购买产品的问题,您需要创建一个新的微服务,该服务将使用自己的数据库存储客户购买的产品。
    对于分析和统计,您需要将所有数据库的数据发送到报告模块。换句话说,您需要构建一个ETL过程。通常使用消息代理,例如Apache Kafka。该页面很好地描述了这种方法。
    构建微服务架构是一项非常复杂和广泛的任务,涉及许多问题和设计模式,可以帮助您将这些问题最小化。我建议阅读一本名为“Microservices patterns”的书,该书介绍了各种微服务架构设计模式。

    8
    在分片数据库模式的链接中,是否提到将多个微服务共用一个单一数据库是反模式? - Totoro
    1
    “共享数据库”(https://microservices.io/patterns/data/shared-database.html)被认为是一种反模式。更好的选择是使用“每个服务一个数据库模式”(https://microservices.io/patterns/data/database-per-service.html)。 - V. Mokrecov
    我认为他的问题更多是:使用一个DBMS实例(例如,一个运行在一个端口上并可被所有微服务访问的postgres),还是使用多个实例(每个微服务一个postgres实例;每个实例运行在不同的端口上;只能被该微服务访问);他并没有谈论数据库名称... - Aniss Chohra
    共享数据库并不是反模式,只是一种建议。微服务通常基于业务能力或功能而设计和部署,而不是绑定到特定的数据库或表。微服务架构是一种构建软件系统的方法,将大型复杂应用程序分解为更小、独立可部署的服务,每个服务都具有其自身的独特功能。每个微服务应专注于特定的业务能力或领域,并应具有与其他服务通信的明确定义接口。 - Rocky4Ever
    虽然微服务可以负责特定的数据库或表,但这并不是架构的要求。相反,微服务通常被设计为通过API或其他接口与数据进行交互,这可以使它们在需要时从多个来源或数据库访问数据。 - Rocky4Ever
    如果您尝试在每个服务的数据库(https://microservices.io/patterns/data/database-per-service.html)中搜索单词“anti”,您会发现该文章标题为“共享数据库反模式”。 - V. Mokrecov

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接