微服务架构的数据设计模式

最近参与公司项目研发,在其中发现对于数据的管理存在一些小问题,根据以往经验,在这里记录下微服务数据设计模式。

微服务架构中的服务是松耦合的,可以独立开发、部署和扩展。每个微服务都需要不同类型的数据和存储方式,也因为这样每个微服务都有自己的数据库。

一、每个服务的数据库

每个微服务都有自己的数据库,可以自由选择如何管理数据。

1.1 每个服务都有一个数据库的好处

  • 松耦合,各自服务可以更加专注自己的专业领域
  • 自由选择数据库类型,如 MySQL 等 RDBMS、Cassandra 等宽列数据库、MongoDB 等文档数据库、Redis 等键值存储和 Neo4J 等图形数据库。

是否需要为每个服务使用不同的数据库服务器?这不是一个硬性要求。让我们看看我们能做些什么。

1.2 如果您使用的是 RDMS,那么就包括以下特性:

  • 专用表—每个服务拥有一组表,只能由该服务访问。
  • 专用数据库架构 —每个服务都有一个私有的数据库架构。
  • 专用数据库服务器 —每个服务都有自己的数据库服务器。

1.3 每个服务都有一个数据库的挑战

需要连接多个数据库的查询 —以下数据模式可以克服这一挑战。

  • 事件溯源
  • API 组成
  • 命令查询职责分离 (CQRS)

跨多个数据库事务 —为了解决这个问题,我们可以使用Saga 模式


二、事件溯源

通过事件溯源,业务实体的状态由一系列状态变化的事件跟踪。每当业务实体的状态发生变化时,都会将新事件添加到事件列表中。由于保存事件是一个单一的操作,它本质上是原子的。通过重放事件,应用程序重建实体的当前状态。

应用程序将事件保存在事件存储中,事件存储是事件数据库。可以使用其 API 从存储中添加和检索事件。事件存储也充当消息代理。服务可以通过其 API 订阅事件。当服务在事件存储中保存一个事件时,它会发送给所有感兴趣的订阅者。当实体有大量事件时,应用程序可以定期保存实体当前状态的快照以优化加载。应用程序查找最近的快照以及自该快照以来发生的事件以重建当前状态。这减少了要重播的事件的数量。

2.1 事件溯源的好处

  1. 使用它解决了事件驱动架构的关键挑战之一,并使得在状态变化时可靠地发布事件。
  2. 避免了对象关系阻抗不匹配问题,持久化事件而不是域对象。
  3. 对实体提供 100% 可靠的审计日志。
  4. 允许执行确定实体在任何时间点的状态的时间查询。
  5. 基于事件溯源的业务逻辑涉及交换事件的松散耦合实体。使从单体应用程序迁移到微服务架构变得容易得多。

2.2 事件溯源的缺点

  1. 有一定学习成本,目前还是一种不太成熟的技术。
  2. 查询事件存储很困难,需要一个典型的查询来重建实体状态。可能会导致低效和复杂的查询。因此,应用程序必须使用命令查询职责分离 (CQRS) 来实现查询。反过来,这意味着应用程序必须处理最终一致的数据。

三、API 组成

您可以使用 API 组合模式实现从多个服务中检索数据的查询操作。在这个模式中,通过调用拥有数据的服务然后组合结果来实现查询操作。

3.1 API 组合的好处

在微服务架构中查询数据的一种便捷方式。

3.2 API组合的缺点

有时,查询会导致大型数据集的低效内存连接。


四、命令查询职责分离 (CQRS)

RDBMS 通常用作记录事务系统和文本搜索数据库,例如用于文本搜索查询的 Elasticsearch 或 Solr。一些应用程序通过同时写入两者来保持数据库同步。其他人定期将数据从 RDBMS 复制到文本搜索引擎。基于此架构构建的应用程序利用了多个数据库的优势、RDBMS 的事务属性以及文本数据库的查询能力。CQRS 概括了这种架构。

微服务架构在实现查询时面临三个常见挑战。

  1. 使用 API 组合模式检索分散在多个服务中的数据,从而导致成本高昂且效率低下的内存连接。
  2. 数据以不能有效支持拥有数据的服务所需查询的格式或数据库中存储。
  3. 分离关注点意味着拥有数据的服务不应该负责实现查询操作。

这三个问题都可以通过使用 CQRS 模式来解决。

CQRS 的主要目标是分离或分离关注点。因此,持久数据模型分为两部分:命令端和查询端。

创建、更新和删除操作由命令端模块和数据模型实现。查询由查询端模块和数据模型实现。通过订阅命令行发布的事件,查询端保持其数据模型与命令端同步

4.1 CQRS 的好处

  1. 实现高效查询实现 —如果您使用 API 组合模式来实现查询,您可能会遇到大型数据集的高成本、低效的内存连接。对于这些查询,使用预先来自连接两个或更多服务数据的CQRS 视图更有效。
  2. 能够有效实现多种查询 —通常很难使用单一持久数据模型来支持所有查询。在CQRS 中,定义一个或多个视图有效地实现特定查询,消除了单个数据存储的限制。
  3. 实现基于事件溯源的应用程序中查询 —CQRS 还克服了事件溯源的一个重要限制。事件存储仅支持基于主键的查询。CQRS 模式通过定义一个或多个聚合视图来解决此限制,这些视图通过订阅由事件源聚合发布的事件流来保持最新。
  4. 关注点分离改进 —域模型和持久数据模型不支持命令和查询。CQRS 将服务的命令和查询端分离为单独的代码模块和数据库模式。

4.2 CQRS 的缺点

  1. 更复杂的架构—为了更新和查询视图,开发者需要编写查询端服务。应用程序可能使用不同类型的数据库,这增加了开发人员和 DevOps 的复杂性。
  2. 处理复制延迟 —在从命令端发布事件到由查询端处理事件以及更新视图之间存在延迟。

五、Saga模式

使用 sagas,您可以在不使用分布式事务的情况下保持微服务架构中数据的一致性。您为跨多个服务更新数据的每个命令定义一个 saga。saga 是一系列本地事务。本地事务使用ACID事务框架更新单个服务中的数据。

Sagas 利用补偿事务来回滚更改。假设saga的第n个交易失败。必须撤消前 (n-1) 个事务。结果,总共 (n-1) 个补偿事务将被启动以以相反的顺序回滚更改。

5.1 Saga协调

为了实现一个 saga,它需要逻辑来协调其步骤。一旦系统命令启动了一个 saga,协调逻辑必须选择并指示第一个 saga 执行本地事务。一旦该事务完成,编排协调就会选择并调用下一个 saga 参与者。这个过程一直持续到传奇完成。如果本地事务失败,saga 必须以相反的顺序执行补偿事务。

5.2 有几种方法可以构建 saga 的协调逻辑:

编排 :在saga的参与者之间分配决策和排序。他们主要通过交换事件进行通信。

5.2.1 基于编排的saga优势

  1. 简单性 —当创建、更新或删除业务对象时,服务会发布事件。
  2. 简单依赖关系 —不引入循环依赖关系。
  3. 松耦合 —服务实现由编排器调用的 API,因此它不需要知道 saga 参与者发布的事件。
  4. 简化业务逻辑 —在 saga 编排器中,saga 协调逻辑是本地化的。领域对象不知道它们所涉及的 sagas。

5.2.2 基于编排的缺点

  1. 更难理解 —编排将 saga 的实现分布在服务之间,每个服务都是独立的这就需要每个管理对每个服务都需要了解。
  2. 服务之间的循环依赖 —saga 参与者订阅彼此的事件,这通常会产生循环依赖。
  3. 紧密耦合的风险 —saga的参与者必须订阅所有影响他们的事件。

编排 —一个 saga 的协调逻辑应该集中在一个 saga 编排器类中。在 saga 期间,编排器向参与者发送命令消息,告诉他们应该执行哪些操作。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
该项目是采用目前比较流行的SpringBoot/SpringCloud构建微服务电商项目,项目叫 《果然新鲜》,实现一套串联的微服务电商项目。完全符合一线城市微服务电商的需求,对学习微服务电商架构,有非常大的帮助,该项目涵盖从微服务电商需求讨论、数据设计、技术选型、互联网安全架构、整合SpringCloud各自组件、分布式基础设施等实现一套完整的微服务解决方案。 项目使用分布式微服务框架,涉及后台管理员服务、地址服务、物流服务、广告服务、商品服务、商品类别服务、品牌服务、订单服务 、购物车服务、首页频道服务、公告服务、留言服务、搜索服务、会员服务等。  系统架构图   SpringBoot+SpringCloud+SSM构建微服务电商项目使用SpringCloud Eureka作为注册中心,实现服务治理使用Zuul网关框架管理服务请求入口使用Ribbon实现本地负载均衡器和Feign HTTP客户端调用工具使用Hystrix服务保护框架(服务降级、隔离、熔断、限流)使用消息总线Stream RabbitMQ和 Kafka微服务API接口安全控制和单点登录系统CAS+JWT+OAuth2.0分布式基础设施构建分布式任务调度平台XXL-JOB分布式日志采集系统ELK分布式事务解决方案LCN分布式锁解决方案Zookeeper、Redis分布式配置中心(携程Apollo)高并发分布式全局ID生成(雪花算法)分布式Session框架Spring-Session分布式服务追踪与调用链Zipkin项目运营与部署环境分布式设施环境,统一采用Docker安装使用jenkins+docker+k8s实现自动部署微服务API管理ApiSwagger使用GitLab代码管理(GitHub  GitEE)统一采用第三方云数据库使用七牛云服务器对静态资源实现加速 开发环境要求JDK统一要求:JDK1.8Maven统一管理依赖 统一采用Docker环境部署编码统一采用UTF-8开发工具IDEA 或者 Eclipse 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MobotStone

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值