微服务中的关系数据库
Relational DB in microservices
我有一个单体应用程序,目前使用 PostgreSQL 数据库,模式设置与大多数关系数据库的预期一样,其中各种 table 数据通过 [=] 上的 FK 链接回用户10=].
我正在尝试了解有关微服务的更多信息,我正在尝试将我的 python API 迁移到微服务架构。我对如何将较大的应用程序分解成较小的部分有一个合理的理解,但是,我并不完全清楚我应该如何处理数据方面的事情。
我知道一个大型数据库违反微服务的一般设计原则,但我不清楚替代方案是什么。
我最担心的是在保存微服务数据的各个数据库之间进行级联。在一个简单的 rdb 中,我可以级联删除,数据库将处理各种 table 之间的工作。在微服务的情况下,它将如何工作?我是否需要一个单独的服务来处理跨其他服务数据库删除用户数据?
我不太明白如何将具有关系数据库的传统应用程序迁移到微服务架构?
编辑:
澄清一下 - 我面临的一个具体 architectural/design 问题如下:
我已将我的应用程序拆分为几个微服务。在我看来仍然相关的是:
地理定位 - 检查几何数据、PostGIS 中的记录和 returns 某些信息的服务。主要目的是记录特定用户的位置以供以后参考
图片 - 一个简单的上传服务,用于上传图片并将元数据存储在数据库中。
Load-Image - 一项简单的服务,returns 根据位置等参数和用户个人资料数据(如年龄、性别等)随机生成一组图像
个人资料 - 一种简单管理用户数据(例如年龄、性别等)的服务
通常,这三个项目在更大的数据库中都有一个 table,而不是在它们自己的单独数据库中。按位置和年龄过滤图像是一个非常简单的 JOIN 和过滤器。
类似的东西在微服务架构中如何工作?如果数据完全保存在不同的数据库中,我将如何设置过滤数据的逻辑?我可以复制不经常更改的数据,如个人资料信息,并将其添加到 MongoDB 文档中,该文档将包含图像数据,包括 user_id 和个人资料数据 - 但是,位置数据可以定期更改并且不断更新不会听起来很实用。
最好的方法是什么?或者我应该只为那几个服务坚持使用共享 RDBMS?
在微服务架构中,我们有两种选择,要么为每个服务使用数据库,要么使用共享数据库。两种模式各有利弊。每个服务架构的数据库是最佳实践,但当整体应用程序在数据库级别具有大量功能、过程或特定于数据库的功能时,我们可以使用共享数据库方法,我知道如果你有时间和带宽,这不是最佳实践那么你应该为每个服务选择数据库。
由于您关心的是对单个数据库的级联,因此您需要从数据库中删除级联并在您的应用程序中实现全局事务处理并从该事务执行所有与级联相关的查询。
它归结为数据重复、我们为什么需要它以及我们如何管理它。
在我们职业生涯的早期,我们被教导为了冗余目的在复制上下文中复制数据,例如,在数据库复制或备份中。我们还了解到,数据可以以关系方式建模,并通过约束来加强模型的完整性。事实上,模型的完整性是神圣不可侵犯的。没有诚信,你怎么能有一致性?答案是你不能。有点。
当您使用分布式系统和面向服务时,您这样做是因为您希望最小化交互,从而减少组件之间的耦合。然而,这是有代价的。您的体系结构越分散,它的耦合就越少,并且需要更多的数据重复。这在微服务中发挥到了极致,实际上相同的数据可能以不同程度的一致性存在于许多不同的地方。
然而,在这种情况下,数据复制不是坏事,而是您系统的基本特征。它是具有许多巨大优势的架构风格的推动者。换句话说,如果没有重复数据,你会得到更少的分布,你会得到更多的耦合,这使得你的系统的构建、拥有和更改成本更高。
那么,现在我们了解了数据重复以及我们需要它的原因,让我们继续讨论如何管理大量重复数据。举个例子:
在关系数据库中,假设我们有一个名为 Customers 的 table,其中包含客户 ID 和客户详细信息,还有另一个名为 Orders 的 table,其中包含订单 ID、客户 ID , 以及订单详情。假设我们还有一个订购应用程序,如果根据 GDPR 删除客户,则需要删除客户的所有订单。
因为我们正在将我们的系统迁移到微服务,所以我们决定创建一个名为 Customers 的服务。
所以我们通过以下操作创建一个服务:
- DELETE /customers/{customerId} - 删除客户
我们使用以下操作创建另一个名为 Orders 的服务:
- GET /orders/customers/{customerId} - 获取客户的所有订单
- DELETE /orders/{orderId} - 删除订单
我们构建了一个用于删除客户的用户体验屏幕。 UX 首先调用订单服务来获取客户的所有订单。然后它遍历订单列表,调用订单服务删除订单。然后调用客服删除用户
此示例非常简单,但如您所见,除了从调用方编排 "Delete Customer" 操作外别无选择,在本例中为用户界面。当然,数据库中的单个原子事务不会转换为多个 HTTP/s 调用,因此某些调用可能不会成功,从而使整个系统处于不一致状态。在这种情况下,需要通过某种恢复机制来解决不一致问题。
我有一个单体应用程序,目前使用 PostgreSQL 数据库,模式设置与大多数关系数据库的预期一样,其中各种 table 数据通过 [=] 上的 FK 链接回用户10=].
我正在尝试了解有关微服务的更多信息,我正在尝试将我的 python API 迁移到微服务架构。我对如何将较大的应用程序分解成较小的部分有一个合理的理解,但是,我并不完全清楚我应该如何处理数据方面的事情。
我知道一个大型数据库违反微服务的一般设计原则,但我不清楚替代方案是什么。
我最担心的是在保存微服务数据的各个数据库之间进行级联。在一个简单的 rdb 中,我可以级联删除,数据库将处理各种 table 之间的工作。在微服务的情况下,它将如何工作?我是否需要一个单独的服务来处理跨其他服务数据库删除用户数据?
我不太明白如何将具有关系数据库的传统应用程序迁移到微服务架构?
编辑:
澄清一下 - 我面临的一个具体 architectural/design 问题如下:
我已将我的应用程序拆分为几个微服务。在我看来仍然相关的是:
地理定位 - 检查几何数据、PostGIS 中的记录和 returns 某些信息的服务。主要目的是记录特定用户的位置以供以后参考
图片 - 一个简单的上传服务,用于上传图片并将元数据存储在数据库中。
Load-Image - 一项简单的服务,returns 根据位置等参数和用户个人资料数据(如年龄、性别等)随机生成一组图像
个人资料 - 一种简单管理用户数据(例如年龄、性别等)的服务
通常,这三个项目在更大的数据库中都有一个 table,而不是在它们自己的单独数据库中。按位置和年龄过滤图像是一个非常简单的 JOIN 和过滤器。
类似的东西在微服务架构中如何工作?如果数据完全保存在不同的数据库中,我将如何设置过滤数据的逻辑?我可以复制不经常更改的数据,如个人资料信息,并将其添加到 MongoDB 文档中,该文档将包含图像数据,包括 user_id 和个人资料数据 - 但是,位置数据可以定期更改并且不断更新不会听起来很实用。
最好的方法是什么?或者我应该只为那几个服务坚持使用共享 RDBMS?
在微服务架构中,我们有两种选择,要么为每个服务使用数据库,要么使用共享数据库。两种模式各有利弊。每个服务架构的数据库是最佳实践,但当整体应用程序在数据库级别具有大量功能、过程或特定于数据库的功能时,我们可以使用共享数据库方法,我知道如果你有时间和带宽,这不是最佳实践那么你应该为每个服务选择数据库。 由于您关心的是对单个数据库的级联,因此您需要从数据库中删除级联并在您的应用程序中实现全局事务处理并从该事务执行所有与级联相关的查询。
它归结为数据重复、我们为什么需要它以及我们如何管理它。
在我们职业生涯的早期,我们被教导为了冗余目的在复制上下文中复制数据,例如,在数据库复制或备份中。我们还了解到,数据可以以关系方式建模,并通过约束来加强模型的完整性。事实上,模型的完整性是神圣不可侵犯的。没有诚信,你怎么能有一致性?答案是你不能。有点。
当您使用分布式系统和面向服务时,您这样做是因为您希望最小化交互,从而减少组件之间的耦合。然而,这是有代价的。您的体系结构越分散,它的耦合就越少,并且需要更多的数据重复。这在微服务中发挥到了极致,实际上相同的数据可能以不同程度的一致性存在于许多不同的地方。
然而,在这种情况下,数据复制不是坏事,而是您系统的基本特征。它是具有许多巨大优势的架构风格的推动者。换句话说,如果没有重复数据,你会得到更少的分布,你会得到更多的耦合,这使得你的系统的构建、拥有和更改成本更高。
那么,现在我们了解了数据重复以及我们需要它的原因,让我们继续讨论如何管理大量重复数据。举个例子:
在关系数据库中,假设我们有一个名为 Customers 的 table,其中包含客户 ID 和客户详细信息,还有另一个名为 Orders 的 table,其中包含订单 ID、客户 ID , 以及订单详情。假设我们还有一个订购应用程序,如果根据 GDPR 删除客户,则需要删除客户的所有订单。
因为我们正在将我们的系统迁移到微服务,所以我们决定创建一个名为 Customers 的服务。
所以我们通过以下操作创建一个服务:
- DELETE /customers/{customerId} - 删除客户
我们使用以下操作创建另一个名为 Orders 的服务:
- GET /orders/customers/{customerId} - 获取客户的所有订单
- DELETE /orders/{orderId} - 删除订单
我们构建了一个用于删除客户的用户体验屏幕。 UX 首先调用订单服务来获取客户的所有订单。然后它遍历订单列表,调用订单服务删除订单。然后调用客服删除用户
此示例非常简单,但如您所见,除了从调用方编排 "Delete Customer" 操作外别无选择,在本例中为用户界面。当然,数据库中的单个原子事务不会转换为多个 HTTP/s 调用,因此某些调用可能不会成功,从而使整个系统处于不一致状态。在这种情况下,需要通过某种恢复机制来解决不一致问题。