微服务和数据库联接


112

对于将单一应用程序拆分为微服务的人们,您如何处理拆分数据库的难题。出于性能和简单性的原因,我从事的典型应用程序进行了很多数据库集成。

如果您有两个逻辑上不同的表(如果有的话,则是有界上下文),但是经常对大量数据进行汇总处理,那么在整体中,您很有可能避免面向对象,而是使用数据库的标准JOIN功能可在将聚合视图返回到您的应用程序层之前处理数据库上的数据。

您如何证明将此类数据拆分为微服务是合理的,因此可能需要您通过API(而不是数据库)“联接”数据。

我读过Sam Newman的《微服务》一书,在有关拆分Monolith的章节中,他举了一个“打破外键关系”的示例,他承认通过API进行联接会比较慢-但他继续说是否您的应用程序是否足够快,是否比以前慢?

这似乎有点不高兴吗?人们的经历是什么?您使用什么技术来使API联接的性能令人满意?


2
好问题,我遇到了同样的问题,最终我得到了具体化的视图并对此进行了连接。我不喜欢它,但是我想这对微服务将是一个挑战。没有正确的方法来做到这一点,它只是要进行设计的一种选择。我知道很多人说我们可以有一个具体化的观点,但是汇总的响应成为一个问题。让我知道您是否发现更好的东西。
PavanSandeep

我知道这很旧,但是graphql可以解决吗?我也在针对分段迁移进行调查,似乎graphql是实现此无缝连接的方法。
themightybun

在某些时候,您应该认识到教条主义不是走的路。GraphQL是在数据源外部进行聚合的一个很好的例子,它通常可以正常工作。
Christian Ivicevic

Answers:


26
  • 当性能或延迟无关紧要(是的,我们并不总是需要它们)时,只使用简单的RESTful API来查询所需的其他数据就很好了。如果您需要对不同的微服务进行多次调用并返回一个结果,则可以使用 API网关模式。

  • Polyglot持久性环境中具有冗余是非常好的。例如,您可以将消息传递队列用于微服务,并在每次更改某些内容时发送“更新”事件。其他微服务将侦听所需的事件并在本地保存数据。因此,无需查询即可将所有必需的数据保留在特定微服务的适当存储中。

  • 另外,不要忘记缓存:)您可以使用RedisMemcached之类的工具来避免过于频繁地查询其他数据库。


25
所有好的建议,但我仍然很难合理化,也许是因为我们已经习惯了在数据库中进行大量处理。我们当前的应用程序具有复杂的存储过程,该过程对大量数据进行处理,然后返回较小的结果集。在微服务架构中,我认为应该将这些实体划分为不同的有界上下文。我们知道当前的方法很丑陋,但是很难证明将所有数据带回应用层进行处理。也许更多的非规范化或预先计算聚合视图会有所帮助。
马丁·贝利

1
我懂了。微服务方法并不适合每个人,因此应谨慎应用。可能您可以从较小的更改开始。
sap1ens

也许程序员StackExchange会是一个更好的地方来问这个问题:programmers.stackexchange.com/questions/279409/...和其他问题标签微服务programmers.stackexchange.com/questions/tagged/microservices
马丁·拜利

9

服务可以具有来自其他服务的某些参考数据的只读复制副本是可以的。

鉴于此,当尝试将整体数据库重构为微服务(而不是重写)时,我会

  • 为服务创建数据库模式
  • 在该架构中创建版本化*视图**,以将该架构中的数据公开给其他服务
  • 对这些只读视图进行联接

这将使您独立修改表数据/结构,而不会破坏其他应用程序。

除了使用视图之外,我还可以考虑使用触发器将数据从一个模式复制到另一个模式。

这将是朝着正确方向逐步发展,建立组件接缝的过程,稍后可以迁移到REST。

*可以扩展视图。如果需要进行重大更改,请创建具有相同视图的v2,并在不再需要旧版本时将其删除。**或表值函数或Sproc。


5

CQRS--命令查询聚合模式是克里斯·理查森(Chris Richardson)的答案。让每个微服务更新其自己的数据模型并生成事件,这些事件将更新具有较早微服务所需的联接数据的实例化视图。此MV可以是经过查询优化的任何NoSql DB或Redis或elasticsearch。这种技术导致最终的一致性,这绝对不错,并且避免了实时应用程序端的加入。希望这个答案。


2

我将针对使用领域(例如运营和报告)分开解决方案。

对于需要为来自其他微服务的数据的单一表单提供数据的微服务(这是可操作的情况),我认为使用API​​联接是必经之路。您不会需要大量数据,可以在服务中进行数据集成。

另一种情况是您需要对大量数据进行大查询以进行汇总等(报告情况)。为此,我会考虑维护一个共享数据库–与您的原始方案类似,并使用微服务数据库中的事件对其进行更新。在此共享数据库上,您可以继续使用存储过程,这将节省您的精力并支持数据库优化。


1

在微服务中,您创建差异。读取模型,例如:如果您有两个差异。有界上下文,有人想在这两个数据上进行搜索,然后有人需要侦听来自有界上下文的事件,并创建一个特定于该应用程序的视图。

在这种情况下,将需要更多的空间,但是不需要连接,也不需要连接。

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.