面向微服务架构的分布式数据库设计风格
Posted
技术标签:
【中文标题】面向微服务架构的分布式数据库设计风格【英文标题】:Distributed database design style for microservice-oriented architecture 【发布时间】:2018-08-13 06:53:17 【问题描述】:我正在尝试将一个单体应用程序转换为面向微服务的架构风格。后端我正在使用 spring , spring boot 框架进行开发。前端我使用 Angular 2。并且还使用 PostgreSQL 作为数据库。
我的困惑是,当我将数据库设计为分布式时,根据功能,它可能包含 5 个数据库。表示我是按照垂直分区设计的。然后我在考虑实现微服务间的通信服务来实现整个功能。
我认为的另一种方式是水平划分当前结构。所以我的领域是基于一些教育大学。因此,一半的大学属于一个数据库,其余的将属于另一个数据库。并根据两个区域部署服务(两个为两组大学)。
目前我决定继续使用最后提到的方法。我对这些类型的任务很陌生,因为它指的是一些架构任务。我也是这个微服务和分布式数据库世界的初学者。有人会确认我的方法可以解决我的问题吗?我可以继续我的第二种方法 - 根据域对象对数据库进行水平分区吗?
【问题讨论】:
【参考方案1】:目前我决定继续使用最后提到的方法。
如果您希望您的数据库具有水平可扩展性(针对越来越多的客户端连接进行扩展),您最好使用一种旨在作为可扩展的分布式系统工作的技术。类似于CockroachDB 或NoSQL。例如 Cockroachdb 内置了数据分片和复制,并允许您根据需要添加服务器节点来增长。
当我将我的数据库设计为分布式时,根据功能,它可能包含 5 个数据库
这听起来您的总体思路是正确的——按域功能划分。这是一个指向 previous answer 的链接,该链接是关于使用微服务进行通用数据库设计的。
【讨论】:
【参考方案2】:在微服务世界中,每个微服务都拥有一组功能以及由这些功能操作的数据。如果一个微服务需要另一个微服务拥有的数据,它不能直接访问另一个微服务维护/拥有的数据库,而是调用另一个微服务公开的 API。
现在,关于数据的放置,有多种选择 - 您可以将微服务拥有的数据存储在 NoSQL 数据库中,例如 MongoDB、DynamoDB、Cassandra(这实际上取决于微服务的用例),或者您可以使用SQL 数据库的单个实例中的每个微服务的不同表。但是请记住,如果您选择具有多个表的 SQL 数据库的单个实例,那么不同微服务拥有的表之间将没有连接(基本上没有交互)。
我建议您从小处着手,然后在系统使用量增长时考虑数据库扩展问题。
【讨论】:
谢谢您的回复先生。如果我垂直分割数据库,那么它将适当地实现面向微服务架构的实际好处。但在我的场景中,我的不止一个功能从同一个表中获取数据。因此,如果我为不同的服务选择该数据库,CRUD 操作将不会同步,因为我将同一个数据库用于多个独立服务。那么在这种情况下,我需要如何管理我的数据库碎片和服务设计?你能检查一下我在这些声明中提到的观点吗? 基本上,为每个微服务拥有一个单独的数据库的部分原因是由于您有多个写入器时的问题。如果只有 1 个微服务可以更改该表中的数据,则问题会更少。其他微服务从这些表中读取数据是没有问题的(但是你肯定会失去松耦合的好处)。没有什么可以阻止您直接从其他微服务拥有的表中读取数据,但访问该数据的首选方式是通过该数据所有者的 API。 如果你还想绕过API路由直接读取数据,另一种方法是通过维护相同数据的多个表(多组)来进行一些重复(你不需要的地方)担心同步。每个写事务都会同时更新所有重复的表)。每个微服务都将维护自己感兴趣的数据集。写入将仅通过 1 个微服务进行,但所有表中的数据将同时更新。【参考方案3】:我可以继续我的第二种方法 - 水平分区 根据领域对象的数据库?
暂时可以,如果基于此您能够扩展当前系统以满足您的需求。
现在让我们考虑一下为什么首先要迁移到 Microserices 作为一种开发风格。
-
小型组件 - 更易于管理
可独立部署 - 持续交付
多种语言
代码是围绕业务功能组织的
和.....
在迁移到微服务时,您不应该让多个服务直接从彼此的数据库中读取,这会使它们紧密耦合。
一个服务应该完全不知道另一个服务是如何设计其内部结构的。
现在,如果您想转向微服务并充分利用它,您应该按照您的说法进行垂直分区,并且服务可以相互通信。
此外,在转向微服务时,您还会遇到很多其他问题。我尝试在 link 上编译如何开始使用微服务。
如何区分从同一个表中读取数据的服务:
现在让我们首先创建一个虚拟示例:我们有三个服务 Order 、 Shipping 和 Customer 都是三个不同的微服务。
以下是多个服务需要来自同一个表的数据的方式:
-
服务一需要从其他服务读取数据以进行验证等操作。
订单和运输服务可能需要客户服务提供一些数据来完成他们的操作。
例如:在下订单时,会调用带有 customer id 的 Order Service API,现在 Order Service 可能需要验证其是否为有效客户。
一种方法数据库级别的暴露——不推荐——使用相同的客户表——将订单服务绑定到客户服务实现
另一种方法,调用另一个服务获取数据
Variation - 1 致电客服查询客户是否存在并获取一些客户数据,如姓名,并将其保存在订单服务中
变化 - 2 在下订单时不验证,在 OrderPlaced 事件上与客户服务异步检查,并在需要时验证和更新订单状态
我建议根据您想要的一致性调用另一个服务来获取数据。
-
在某些用例中,您希望在来自多个服务的数据之间进行单个事务。
例如:删除客户。您可能希望客户的所有订单也应该被删除。
在这种情况下,您需要处理最终一致性,服务 1 会引发事件,然后服务 2 会做出相应的反应。
现在,如果这回答了您的问题,那么请指定在哪种情况下多个服务需要调用另一个服务。
如果还没有解决,你可以发邮件给我 puneetjindal.11@gmail.com,会回复你的
【讨论】:
是的,先生,您的陈述是真实的。无论如何,感谢您的回复并花时间解决我的问题。我已经了解了与垂直碎片以及微服务架构相关的数据库设计最佳实践。我发现与您在此处添加的相同 - 独立创建服务。但我有一个困惑 - 如果我的多个服务功能依赖于同一张表,那么我需要如何管理它?我的 4 个独立功能从同一个表中获取数据。 一般情况下是不会发生的,如果你能给出表格的描述和你的功能将能够更好地提供帮助??? 目前我正在分析。需要这样做。让我说一下我的观点。假设如果某个表包含两个不同微服务中常用的数据,那么 CRUD 操作将不会同步。我有一些土地调查功能。所有服务都引用我的一些常用表。那么在那种情况下我怎样才能实现独立呢?很抱歉没有给出实际的设计。我仍在为这项任务进行分析。仍在对服务数据库管理进行总体构想。 例如 - 我的功能 F1 引用表 T1、T2、T3。参考表 T1、T2、T4、T5 的功能 F2。和 F3 参考表 T1。因此,每个都是来自一个域的独立服务。那么我需要如何为每个功能创建不同的数据库呢? .在这里,我没有透露确切的项目功能,抱歉。我是否需要在一个包含所有表的数据库或不同项目的春季启动项目中实现这三个端点?这种结构将如何出现? ,我面临很多困惑,因为我是服务世界和弹簧靴的新手。 好的,先生。让我看看你的回复。谢谢。以上是关于面向微服务架构的分布式数据库设计风格的主要内容,如果未能解决你的问题,请参考以下文章