暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

微服务的数据管理模式CRUD和CQRS

原创 eternity 2022-10-12
717

微服务的关键组件之一是如何管理和访问数据。与传统的单片或三层应用程序相比,这样做的方法是不同的。有些模式很常见,但其他模式是特定的,需要在纳入解决方案之前进行评估。在探索CQRS(包括它与CRUD的区别)之前,我们将简要介绍一些微服务的常见数据库模式,最后,看看如何将其与事件来源相结合。

微服务通用数据库模式

在微服务上下文中使用数据库有多种模式。在本节中,我们将从最常见的模式之一开始介绍一些。

每个微服务的数据库

与“一刀切”不同,每个微服务使用一个数据库有助于确保每个服务都可以根据其基于数据存储、建模等的需求使用数据库。在某些情况下,关系数据库是最合适的,而其他用例将受益于键值甚至基于文档(JSON)的数据库。底层数据库的细节由特定于服务的API进行抽象,最终形成灵活且松散耦合的体系结构。

API组成

每个服务都有自己的数据库,并通过每个微服务模式的数据库公开其API。

API组合模式引入了另一个抽象级别,其中API组合器组件负责查询各个服务的API。这种分散-聚集类型的方法通过为客户端应用程序提供统一的接口来避免复杂性。

Saga

这是一种高级模式,有助于克服数据库/微服务模式带来的限制以及微服务体系结构的分布式特性。这些模式需要与多个服务(及其各自的数据库)交互,使得事务工作流(符合ACID)难以实现。Saga模式涉及编排多个本地(特定于服务的)事务,并执行一个补偿事务以在出现故障时撤消它们。

命令查询职责分离和事件来源

与saga模式一样,命令查询职责分离(CQRS)和事件源是涉及分离读写路径的相对高级技术。下一节将详细讨论CQRS,以及它与另一种广泛使用的技术(创建、读取、更新、删除(CRUD))的比较。

CQRS和CRUD

让我们对这些术语有一个基本的了解。

CRUD

基于CRUD的解决方案通常用于实现简单的应用程序逻辑。例如,以处理用户注册、列出用户、更新用户信息(启用/禁用)和删除用户的用户管理服务为例。CRUD之所以如此吸引人,是因为它使用单一的数据存储,并且很容易理解,因此很容易接受常见的体系结构模式,例如HTTP上的REST(JSON是广泛使用的数据格式)。

CQRS

与基于CRUD的解决方案不同,CQRS是关于在单个数据库内或跨多个数据库使用不同的数据模型进行读写操作。这允许独立管理应用程序的读/写部分。例如,您可以有单独的数据库表用于读/写操作,或者利用读副本扩展读负载大的应用程序。

image.png

CRUD和CQRS:差异

让我们了解更多关于CQRS的信息,并在此过程中,通过检查各种特性,了解它与CRUD的区别。

数据存储类型

如前所述,可以使用单个或多个数据存储来实现CQRS。对于单个数据库,您可以使用诸如单独的读/写表和读副本等技术。或者,您可以利用不同的数据库来满足操作的读/写路径的特定要求,例如,您可以使用具有ACID语义的关系数据库来处理中低级写工作负载,并使用内存缓存(如Redis)来服务读请求。

同步或异步

CRUD操作大多以同步方式执行,但根据编程语言和客户端库的不同,可以在客户端进行异步实现。CQRS也可以以同步方式实现,但这种情况很少见。由于CQRS涉及多个数据存储(相同或不同的数据库),因此它受益于一种机制,其中读取模型会根据写入数据存储中的更改进行异步更新。例如,在RDBMS表中插入(或更新)的用户信息会导致Redis以高规模/大容量进行低延迟读取。但这种方法迫使我们考虑另一个重要属性——一致性。

一致性

由于CRUD系统本质上是同步的,并且得益于ACID支持(在关系数据库中),因此它们获得了强大的一致性(几乎免费)。使用CQRS实现,由于其异步特性,您的体系结构需要实现最终的一致性,并确保您的应用程序能够容忍读取(可能)陈旧数据,即使读取时间可能很短。

可扩展性

CQRS解决方案可以利用多个数据存储,并且可以异步操作,这一事实使它们具有更好的可伸缩性。例如,如果需要,利用单独的数据存储可以优化高读卷。CRUD解决方案的可扩展性受到单个数据存储和同步操作模式的限制。

复杂性

听起来很明显,使用CQRS模式构建应用程序非常复杂。如前所述,您可能需要使用多个数据存储,实现它们之间的异步通信,并处理最终的一致性及其警告。CRUD操作得到了很好的理解和广泛的使用,因此通常有很好的支持,例如代码生成器、对象关系建模库等,这大大简化了开发过程。

image.png

CQRS和Event Sourcing—更好地合作?

通过事件源,CQRS中的“C”(代表命令)变得活跃起来。系统的写入部分现在负责将命令存储在事件存储中,而读取部分则完全是关于数据的非规范化形式,这种形式也称为物化视图,支持对UI或应用程序的特定查询。基于事件源和CQRS的解决方案可能在多个数据存储中有多个这样的视图。通常,数据存储本身就支持这些模式,例如Postgres、Cassandra等。

事件不是普通数据,它们代表系统中的操作;因此,write模型利用了一个只附加的、不可变的数据存储。有时,事件源解决方案也会在写入路径中利用流平台,如Apache Kafka,而不是传统的SQL/NoSQL数据库。

image.png

让我们看一个简单的例子。想想推特(Twitter)这样的应用程序中有限的功能子集——用户发送推文,相互关注,并查看他们关注的用户的推文。一个简单的解决方案是,当用户推特时,跟随者的时间线会同步更新。对于用户可以拥有数百万追随者的系统来说,这是不可扩展的。更好的方法是将其分为不同的部分,其中“tweet sent”(命令)用作事件,可以触发关注者的时间轴更新,这可以异步进行。随后,追随者可以看到推文,推文将由解决方案的“查询”部分处理,并可能由不同的数据存储支持-系统必须容忍最终的一致性,这对于这个特定用例是可以接受的。

利弊

Event Sourcing和CQRS确实给了你很多权力,但随之而来的是巨大的责任。如果您没有复杂的数据模型,请坚持使用基于CRUD的解决方案来简化总体架构。

事件源包括以仅附加的、不可变的方式捕获命令/事件(改变了系统),这意味着如果需要,可以重放“历史”数据来重建系统的某些/整个部分。然而,在实际场景中这并不容易,需要对此类流程进行良好规划,以将停机时间和服务中断降至最低。如果您的应用程序没有如此密集的需求,最好避免事件源/CQRS。

您的体系结构处理事件,您可以构建多个应用程序来处理这些事件。例如,用户创建的事件可以触发发送电子邮件处理程序,而另一个处理程序可以处理不同的操作(并行)。同时,您需要考虑错误处理、重试和最终一致性。请注意这些要求,如果您的应用程序无法容忍最终的一致性,请不要使用CRQS/事件来源。

结论

随着微服务成为标准,出现了许多技术和模式来解决其日益复杂的问题。基于CRUD的解决方案被广泛使用,但也有其局限性。高级模式(如CQRS和事件源)有助于提高可伸缩性,但您需要避免陷入过早优化的陷阱。为工作使用正确的工具/模式对长期的应用程序可维护性有很大帮助。

原文标题:Data Management Patterns for Microservices
原文作者:Abhishek Gupta
原文链接:https://dzone.com/articles/data-management-patterns-for-microservices

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

目录
  • 微服务通用数据库模式
    • 每个微服务的数据库
    • API组成
    • Saga
    • 命令查询职责分离和事件来源
  • CQRS和CRUD
    • CRUD
    • CQRS
  • CRUD和CQRS:差异
    • 数据存储类型
    • 同步或异步
    • 一致性
    • 可扩展性
    • 复杂性
  • CQRS和Event Sourcing—更好地合作?
  • 利弊
  • 结论