微服务和数据存储


25

我正在考虑将整体式REST API移至微服务体系结构,并且对数据存储有些困惑。如我所见,微服务的一些好处是:

  • 水平可伸缩-我可以运行微服务的多个冗余副本以应对负载和/或服务器故障。
  • 松散耦合-我可以更改微服务的内部实现而不必更改其他服务,并且我可以独立部署和更改它们等。

我的问题是数据存储。在我看来,有几种选择:

  1. 所有微服务共享一个数据库服务-这似乎完全消除了松耦合的任何好处。
  2. 每个微服务上的本地安装的数据库实例-我看不到横向扩展此方法的方法,因此我认为这不是一个选择。
  3. 每个微服务都有自己的数据库服务-这似乎是最有前途的,因为它保留了松散耦合和水平扩展的优势(使用冗余数据库副本和/或跨多个分片)

在我看来,第三种选择似乎是唯一的选择,但是对我来说,这似乎是难以置信的沉重负担,并且是一种过度设计的解决方案。如果我理解正确,那么对于具有4-5个微服务的简单应用程序,我将必须运行16-20台服务器-每个微服务两个实际的微服务实例(以防服务器故障,并且在不停机的情况下进行部署),以及每个微服务有两个数据库服务实例(如果发生服务器故障等)。

坦率地说,这似乎有些荒谬。要记住,一个现实的项目可能会提供4-5个以上的服务,而16-20个服务器运行一个简单的API,该不该?我是否缺少一些基本的概念来解释这一点?

回答时可能会有所帮助的一些事情:

  • 我是该项目的唯一开发人员,并将在可预见的将来。
  • 我正在使用Node.js和MongoDB,但是我对与语言无关的答案很感兴趣-一个答案甚至可能是我使用了错误的技术!

为什么每个微服务都需要另一个数据库服务?由于已经具有数据库领域知识,因此可以将数据库服务工作添加到相应的微服务本身下。是不是
Sazzad Hissain Khan

Answers:


20

在这三个选项中,最常见的是第一个(单个共享数据库)和第三个(“数据库服务”)。

第一个称为集成数据库。在微服务架构中,这通常不被视为一个好的解决方案。它确实增加了服务的耦合。这也使一个服务非常容易地简单地绕过另一个服务并直接查询数据库。您可能会失去应用程序级别提供的,不在数据库级别强制执行的任何类型的数据完整性或验证。

您的第三个想法称为应用程序数据库。没错,它允许您在服务之间的API级别上实施松散耦合,并允许您更轻松地在数据库级别扩展服务。这也使将基础数据库技术替换为适合每个服务的操作变得更容易,就像您可以更改每个服务的技术或其他实现细节一样。非常灵活。

但是,我建议一种中间解决方案。

代替为每个微服务建立数据库服务,而为每个服务建立架构。如果您正在使用多种数据库技术,则可能需要稍微拆分一下,但是这样做的目的是最大程度地减少正在运行的数据库服务器的数量,但是如果和必要时。只要只允许数据库访问其自己的模式,就可以拥有应用程序数据库的优点,而不会为每个应用程序或服务都存在数据库服务器。

但是,作为一个单独的开发人员,我会在此时挑战整个微服务的概念-Martin Fowler撰写了有关Monolith FirstMicroservice Premium的文章,Simon Brown谈论了模块化的整体著作,而DHH谈到了Majestic Monolith。我不确定您的整体结构组织得如何,但可以对其进行重构和组织。确定组件并在它们之间进行清晰的分离,以便将零件轻松提取到服务中。您的数据库结构也是如此。专注于可以支持重构为服务的良好,干净,基于组件的体系结构。微服务增加了单个开发人员在操作中构建和支持的开销。但是,一旦确实需要扩展系统的一部分,就可以使用监视和报告系统来识别瓶颈,提取到服务并根据需要进行扩展。


1

每个微服务都有自己的数据库服务-这似乎是最有前途的,因为它保留了松散耦合和水平扩展的优势(使用冗余数据库副本和/或跨多个分片)

同意。在第三个选项是微服务的自然选择。如果微服务实际上是独立的(不是分布式整体的一部分),则通常每个服务都有一个数据库。

daccess-ods.un.org daccess-ods.un.org每个微服务有两个实际的微服务实例(如果发生服务器故障,并且可以在不停机的情况下进行部署),每个微服务有两个数据库服务实例(例如,服务器发生故障等)。

如果您希望实现负载平衡,那么您对运行的微服务的数量是正确的。如您已经解释的那样,如果您打算拥有4个微服务,则需要为每个微服务准备至少2个实例(总共8个)。

但是每个微服务有两个数据库?这真是个问题。我不知道您的微服务将要涉及的业务问题的详细信息,但是具有数据库冗余,对于大多数产品/项目来说,这都是很多的。我将建议从一个具有良好备份的单个数据库开始,并(至少在开始时)最小化基础架构的复杂性。

坦率地说,这似乎有些荒谬。要记住,一个现实的项目可能会提供4-5个以上的服务,而16-20个服务器运行一个简单的API,该不该?我是否缺少一些基本的概念来解释这一点?

对于简单的 API,此数字不匹配。如果您没有落入“微服务优先” 陷阱之一,请注意。


我要补充一点,就数据库而言,明智的启动冗余的地方实际上是在硬件级别,尤其是RAID和存储备份。诚然,您无法保证100%的正常运行时间,因为与存储无关的事情可能会出错(麻烦,可能只是软件崩溃),但是与数据丢失相比,这些问题通常没什么大不了的。如果您担心支出,那么您肯定首先要专注于简单的数据完整性,然后再考虑正常运行时间的最大化。

0

服务是面向服务架构的一种形式,也许在极端情况下。它们的一般目的是减少耦合并允许独立开发和部署。

从体系结构的角度来讲,微服务是一个在逻辑层面上适用的术语。微服务在逻辑上彼此分离。从这个角度来看,微服务应各自拥有并提供自己的存储,这些存储应与其他微服务的存储分离。对于微服务而言,存储的独立性是实现模块化和松耦合目标的关键。

从体系结构的角度来看,水平缩放适用于更低的级别,更接近于实现(例如,物理级别)。在此级别上,我们正在实现微服务,并且可以在内部将单个微服务分解为可水平伸缩的无状态组件,以及所有无状态组件共享的有状态组件。  但是,我们不要仅将无状态部分与微服务本身混淆。

因此,当我们谈论单个微服务时,我们是在逻辑上谈论API,分离的职责和分离的开发/部署周期。当我们谈论水平扩展时,我们在物理层面上谈论的是(单个)微服务的实现及其分解为无状态和有状态组件。

在实现多个微服务时,我们可以选择为有状态组件重用数据库技术:

  • 每个微服务独立的数据库
  • 共享数据库:
    • 每个微服务的单独/私有架构
    • 每个微服务的单独/专用表

在这里查看更多。

所有微服务共享一个数据库服务-这似乎完全消除了松耦合的任何好处。

同意,如果您要共享表的行和列,那实际上不是微服务。

如果我们能够在思想过程中将微服务的逻辑概念与微服务的有状态和无状态组件的更物理概念解耦,那么我们可能会发现更容易实现微服务提供的松散耦合,同时保持共享的效率数据库。

通常,有关微服务和有状态持久性的文章很多,请参见此处


-1

好吧,我已经阅读了该线程中的所有帖子,并可以告诉您我对这个问题感到困惑:它将微服务(MS)与服务以及数据访问服务(DB服务)与数据库和服务器混合在一起...

如果MS是一个独立的(可部署的)组件,以无状态的方式解决了一个最简单的任务,那么它需要哪个数据库?如果要解决的更复杂的任务需要同时解决多个最简单的子任务(MS?),那么它仍然是MS吗?在SOA中,它称为协调服务。它实现“过程”并协调MS调用,因此它需要保持其状态(所有业务流程/组织者/撰写者/等都是有状态的),并且需要一个个人数据存储区:没有其他人可以调整协调器的状态。

但是,我们谈论的不是数据库,而是数据库访问MS / Service,这是完全不同的事情。一个MS可能需要在公司中收集一些数据(而不是在它所运行的应用程序中),并且它不能通过其API /接口向另一个MS询问数据。这是最常见和现实的情况。来自相同或不同应用程序的另一个MS可能需要此数据甚至更改它。是的,他们像MS出现之前一样一直在争夺数据。

为什么我们要撞毁众所周知且开放的“门”?MS与常规自持对象之间在这方面有何区别?如果我们无论如何(出于灵活性和可组合性目的)都必须使用其数据访问服务(DAS),为什么我们需要一个单独的MS数据库?不要忘记,DAS可以保护执行业务任务的MS,使其免受与数据库物理连接的了解。MS应该保留这种松散耦合和灵活性,以自由地参与多个没有数据库锚定的应用程序。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.