微服务架构下的【数据库管理】最佳实践

原文在公众号:【JavaEdge】

本文探索有效的微服务数据库管理的最佳实践。

0 概述

什么是微服务数据管理模式?

微服务数据管理模式帮助管理软件不同组件的数据。数据管理模式方便两个或多个软件组件的数据库之间的通信。

数据管理模式

  1. Database per service pattern
  2. Shared database pattern
  3. API Composition pattern
  4. Saga Pattern
  5. CQRS Pattern
  6. Event Sourcing Pattern
  7. Database Sharding Pattern

1 每个服务一个DB

每个微服务都有其自己的私有数据库,使服务松耦合。

每个服务一个数据库模式易于使用,适用于新应用程序。微服务模式提供:

  • 高可扩展性
  • 数据库之间的松耦合
  • 简单的影响分析

优点

隔离和独立性

每个微服务都有专用数据库,这确保了数据的完全隔离。这种隔离允许每个服务独立运行,而不会干扰其他服务。一个微服务数据库的更改和更新不会影响其他微服务。

自治开发和部署

微服务团队可以自主地在各自的服务和数据库上工作。这种自治性导致了更快的开发和部署周期,因为团队可以在不与其他团队协调的情况下发布更新。

技术灵活性

不同的微服务可以使用最适合其特定需求的数据库技术。这种灵活性意味着您可以为一个微服务选择关系数据库,为另一个微服务选择 NoSQL 数据库,或者甚至根据要求选择缓存机制。

可扩展性

扩展简化了,因为每个微服务可以根据其独特的需求独立扩展其数据库。遭受高流量或数据负载的服务可以扩展其数据库,而不会影响其他服务。

减少耦合

通过避免微服务之间的直接数据库访问,可以减少它们之间的耦合。微服务通过定义良好的 API 相互交互,这允许松耦合并更大的灵活性来更改服务。

显著优势,包括增加的敏捷性、可扩展性、独立性和改进的数据管理。然而,也带来挑战,如确保数据一致性并实现微服务之间有效的通信模式,需仔细考虑和实施。

2 共享DB(Shared Database Pattern)

创建单一的数据库,该数据库由不同的微服务共享。

创建一个单一的共享数据库,每个服务使用本地ACID 事务访问数据。但这与微服务的本质相矛盾,给应用程序的未来带来严重问题。最后,我们将面临开发大型单体应用程序而不是微服务的问题。

适用场景

在遗留应用程序中很有用,在读负载高于写负载的简化应用程序中很有用,但当应用程序变大时,迁移到每个服务一个数据库模式是可行的,因为共享数据库模式可能导致服务之间紧耦合,在这里我们不允许使用不同的技术,因为我们有共享数据库,这可能导致缺乏可扩展性和单点故障。

3 API 组合(API Composition pattern)

将来自多个微服务的数据聚合和合并为对客户端或另一个服务的单个响应。它允许向使用者提供数据的统一视图,而无需他们对不同的微服务进行多次 API 调用。

这简化客户端开发,减少延迟并最大限度减少数据的过度获取和获取不足。

所以这里客户端向网关请求,需要由不同微服务处理的所有组合请求都由聚合器传递给不同的微服务,最后生成单个响应。

与向不同微服务发出多个请求相比,该模式可减少延迟,因为客户端可以在一次请求中检索所有必要的数据,从而减少往返时间。在这里,客户端不需要处理复杂的逻辑来从多个源中获取和合并数据,这使得客户端代码更简单、更容易维护。

4 长事务(Saga Pattern)

管理分布式事务场景中微服务之间数据一致性的方法。Saga 是一系列更新每个服务并发布消息或事件以触发下一个事务步骤的事务。若某步失败,saga 将执行补偿事务来抵消前面事务的效果。

正如每个服务一个DB模式:每个微服务都有自己的DB,但不满足ACID。

构建一个电商,客户有一个信用限额。应用程序须确保新订单不会超过客户信用限额。由于订单和客户位于不同服务拥有的数据库,应用程序无法简单使用本地 ACID 事务。

为解决这问题,踢出 Saga 模式。

Saga 模式使用一系列本地事务提供事务管理。本地事务是 saga 参与者执行的原子工作量。每个本地事务更新数据库并发布消息或事件以触发 saga 中的下一个本地事务。若本地事务失败,saga 将执行一系列补偿事务,这些事务将撤消先前本地事务所做的更改。

saga 实现方法

协调

一种协调 saga 的方法,其中参与者相互交换事件,没有集中的控制点。

编排

一种协调 saga 的方式,其中集中控制器告诉 saga 参与者执行哪些本地事务。

5 CQRS

命令查询职责隔离,软件架构中常用的一种设计模式,特别适用于具有复杂数据处理需求的系统。 CQRS 将:

  • 处理命令(更改数据)
  • 查询(检索数据)

的职责分离到不同的组件。对读写操作具有不同性能、扩展和优化要求的场景,这种模式尤有价值。

关键概念和组件

命令

表示修改数据或执行某种状态更改操作的操作。 示例包括创建、更新或删除记录。 命令会发送到命令处理程序,后者处理命令并可能对系统的数据进行更改。

命令处理程序

负责接收和处理命令。 它包含验证、执行和将更改应用于数据存储的逻辑。 处理命令后,它可能会生成事件来通知系统其他部分所做的更改。

事件

表示系统状态更改的不可变事实。 当它们成功处理命令时,由命令处理程序生成。 事件捕获更改背后的意图,并且通常存储在事件存储中,以进行审计和作为系统状态的真实来源。

事件存储

用于事件的持久存储系统。 它保留了系统中发生的所有事件的历史记录。 事件溯源是一种紧密相关的模式,它使用事件存储通过重播事件来重建应用程序的状态。

查询

代表不更改其状态的读取操作。 查询处理程序负责处理查询并将结果返回给客户端。 与命令处理程序不同,查询处理程序不修改数据。

模型分离

CQRS 系统中,通常在用于写入的模型(命令模型)和用于读取的模型(查询模型)之间进行分离。 这些模型可以独立优化以执行各自的任务。

工作方式

① 命令处理

  • 客户端向相应的命令处理程序发送命令。
  • 命令处理程序处理命令,验证它,应用任何必要的业务逻辑,并可能因此生成事件。
  • 生成的事件存储在事件存储中并发布以通知系统的其他部分。

② 事件处理

  • 事件处理程序侦听事件并更新查询模型以及用于查询处理的任何非规范化数据存储(例如读取数据库或缓存)。
  • 这种分离允许对查询模型进行优化以进行读取,与命令模型相比,可能具有不同的数据结构和模式。

查询处理

  • 客户端向查询处理程序发送查询。
  • 查询处理程序从查询模型中检索数据并将结果返回给客户端。

6 事件溯源(Event Sourcing Pattern)

事件溯源模式基本为累积事件提供了一种方法并将其聚合到数据库中的事件序列中。

7 数据库分片模式(Database Sharding Pattern)

数据分片模式将数据集分离为不同的分片或水平分区,以简化访问和存储。 微服务数据库管理模式中的每个分片具有相同的模式,但保留数据的不同子集。

分片模式允许高可扩展性,因为在存储需求增加时,您可以添加新分片。 此外,通过减少每个服务的工作负载,还可以提高性能。

8 总结

有效的微服务数据库管理是成功的微服务架构的关键组成部分。 通过遵循这些技术和最佳实践,您可以确保微服务保持可扩展、可维护和高性能,同时促进数据一致性和安全性。 保持适应能力并持续监控和优化数据库管理策略,以适应微服务生态系统的发展。

参考:

  • https://learn.microsoft.com/zh-cn/azure/architecture/reference-architectures/saga/saga
#我的求职思考#
2024系统设计面试指南 文章被收录于专栏

面向 2024 校招/社招全网最新最全的系统设计面试。八年开发经验,毕业四年成为技术专家兼架构师,乐于知识分享,擅长图文讲解各种软件技术! 现如今,牛客网人均某马点评,但本质都是系统设计考量点,如: 1.多级缓存设计,如何保证缓存跟数据库的一致性? 2.设计模式,各种业务流程,到底何时何地使用何种模式? 3.玩转分布式框架 ... 更多技术重难点设计,尽在本专栏!

全部评论

相关推荐

11-22 16:49
已编辑
北京邮电大学 Java
美团 质效,测开 n*15.5
点赞 评论 收藏
分享
10-30 23:23
已编辑
中山大学 Web前端
去B座二楼砸水泥地:这无论是个人素质还是专业素质都👇拉满了吧
点赞 评论 收藏
分享
HNU_fsq:建议直接出国,这简历太6了。自愧不如
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
昨天 10:52
点赞 评论 收藏
分享
2 3 评论
分享
牛客网
牛客企业服务