InfoQ 编辑部出品——2021年度技术盘点与展望 了解详情
写点什么

为什么要从 CRUD 转向事件源架构?

  • 2022 年 1 月 14 日
  • 本文字数:2320 字

    阅读完需:约 8 分钟

为什么要从CRUD转向事件源架构?

如果对各种架构风格都有个透彻的理解,设计者就能够构建新型的、反应性的、有弹性的大型应用。因此,遵循这些经过行业检验的标准可以节省时间、保证可靠性,并推动目标实现。毕竟,企业有什么理由要花时间和资源来重新发明轮子?


但仅仅了解不同的架构,如基于 CRUD 的架构、基于微服务的架构和基于事件源的架构,并不足以做出全面的决策。我们需要深入了解细节,并理解它们各自的特性、适用性和所提供的价值。在这篇文章中,我们将看一下 CRUD 和事件源架构,思考为什么应该考虑从前者迁移到后者。

什么是 CRUD?

CRUD 是创建、读取、更新和删除的缩写。它构成了数据库的四个命令,四个不言自明的命令,这些命令被认为是持久性存储管理的必备要素。这种模式被各行各业的企业广泛用于跟踪客户数据、员工信息、支付记录、账户等。


让我们快速说明一下 CRUD 的常规事件流。Gary 正在浏览一个电子商务网站。他把一个游戏机、一个控制器和一个游戏添加到购物车中。此时,购物车的数据库看起来大概是这样:

Customer

Product

Quantity

Gary

Sony PlayStation 5

1

Gary

Sony DualSense Wireless Controller

1

Gary

Assassin's Creed Valhalla

1

假如我们添加另外一个物品(如耳机),则数据库会变成下面这样:

Customer

Product

Quantity

Gary

Sony PlayStation 5

1

Gary

Sony DualSense Wireless Controller

1

Gary

Assassin's Creed Valhalla

1

Gary

Sony PULSE 3D wireless headset

1

如果 Gary 删除了耳机,则表就会变回之前的样子。此外,如果他另外添加一个控制器,则数据库会变成下面这样:

Customer

Product

Quantity

Gary

Sony PlayStation 5

1

Gary

Sony DualSense Wireless Controller

2

Gary

Assassin's Creed Valhalla

1

Gary

Sony PULSE 3D wireless headset

1

本质上,数据库遵循创建-读取-更新-删除的方法来维护表。“更新”和 “删除”功能是 CRUD 的特点。

CRUD 方法的局限性

虽然 CRUD 方法由于其操作的轻量化和简单性而备受青睐,但它也有自己的一系列局限,这包括:

  • 对于 CRUD,最常见的批评是原始、过时。与其说它是一种架构或设计,不如说它是一个可供遵循的循环步骤,不管是构建一个数据库还是一个API

  • CRUD 依赖于数据库中状态的持久性。然而,考虑到当前数据操作事件的动态性,这种信息的存储可能是浪费和资源密集型的。

  • 尽管 CRUD 架构很简单,但在开始阶段,它需要人们花费大量的精力编写大量的代码。尽管如此,当涉及到云负载均衡时,CRUD 却无法胜任。

  • 虽然 CRUD 代码开始时可能很简单,但当它开始与其他服务或微服务共享数据时,就会出现与状态同步和故障处理有关的问题。

  • CRUD 架构所涉及的复杂性将需要同样复杂的解决方案,这可能会延伸到故障跟踪、手动状态记录、异步批处理等。这方面的考虑在编码和整合上都会比较艰难。

  • 在 CRUD 模型中,实体实例通常是双重表示,一是内存中的可变对象,二是关系数据库表中的一个可变行。这样的结构导致了臭名昭著的对象-关系阻抗不匹配。试图弥合这种鸿沟的努力却进一步增加了这一架构的复杂性。

什么是事件源架构?

事件源是一种数据存储技术,被认为是 CRUD 的升级版。它只关注创建和读取功能,而完全省略了 CRUD 中更新和删除值的操作。更简单地说,你不能通过事件源执行破坏性的操作。


那么,它是如何克服 CRUD 面临的挑战的?


这里有个有趣的地方:与 CRUD 遵循的传统方法不同,事件源将变化逐个记录下来,作为当前状态随时间变化的一系列增量,而不是持久化当前状态本身。通过这种方式,事件源赋予了状态变化可追溯性。在大多数情况下,这种设计通常与领域驱动设计(DDD)和命令查询责任分离(CQRS)设计模式相结合。


为了更好地理解事件源架构,让我们以 Gary 的银行账户为例。假设 Gary 的账户里有 2400 美元。他用 499 美元购买了 PS5 游戏机。电子商务网站为他提供了 49 美元的返现。在这种情况下,事件源表会是这样的:

Event

Value

Remark

1

2400

(balance)

2

-499

(debit)

3

+49

(credit)

通过追踪一段时间内的取款和存款,可以计算出他目前的账户余额为 1950 美元。这种状态的复原和事件的回放被称为重放。


我们可以把事件源视为客户活动的日志。


如果我们从电子商务平台的角度来看 Gary 的活动,添加游戏机是第一个事件,添加控制器是第二个事件,以此类推。事实上,结账过程也是一个独立的事件。如果 Gary 不小心在购物车中添加了三个控制器(例如,事件 1、2 和 3),然后他又删除了一个,那么删除也是一个独立的事件:事件 4!

采用事件源架构的好处

从对事件源的基本理解来看,它似乎是一个更好更完善的替代方案,克服了 CRUD 的缺点。为了进一步说明这一点,让我们看一下事件源已被证明了的优势。

  • 事件源遵循事件驱动的架构,方便在状态变化时可靠地发布事件。

  • 它通过持久化事件而不是领域对象,克服了 CRUD 中出现的对象-关系阻抗不匹配问题。

  • 它维护了一系列事件的记录,可以在只限追加的状态下进行操作。通过消除状态跟踪和实体关系的需求,编写读写数据库的事件源代码更容易。

  • 由于保留了实体如何到达当前事件的日志,所以事件源保证了审计数据和交易数据的一致性,因为它们是一样的。此外,它也是一个很好的故障保险,因为数据可以从事件日志中重建。

  • 所有的事件只是被追加到现有的数据库中,并且更新和删除功能已被去掉,事件源架构只关注写入,这提高了其性能。

  • 事件源允许对事件流进行分析,这有助于企业从中获取关键信息。他们可以获得所有系统活动的顶层视图,而不会使写入功能复杂化。

  • 遵循事件源模型的架构更容易测试和调试,因为在引入命令和事件之前,可以对其进行模拟测试。此外,事件日志还可以作为一个很好的调试活动记录,如果发现问题,可以在受控环境中重放事件日志,以了解导致异常的原因。

  • 它可以存储任何类型的信息,任何消费者只要获得授权,就可以访问这些信息。它允许通过时间查询实体在任何时候的状态。因此,它非常灵活。

  • 与单体架构相比,事件源应用程序更容易迁移,因为它们遵循基于微服务的架构。之所以如此,是因为参与事件交换的业务实体之间是松耦合的。

结语

随着越来越多的应用程序需要以有序和异步的方式传递实时数据,企业对事件源的需求也越来越大。此外,它也是在网络规模上消费和管理应用程序日志数据的绝佳方法。在这种情况下,事件源成了一个唯一的事实来源,提高了应用程序的可靠性。


那么,你所在的企业打算何时从 CRUD 迁移到事件源架构?


原文链接:

Why Do You Need to Move From CRUD to Event Sourcing Architecture?


2022 年 1 月 14 日 15:384987

评论 7 条评论

发布
用户头像
事件源配合读写分离才能得到比较好的效果,这两种思想/架构模式一般都是结合使用的。
事件源用于追溯数据的生产源头,然后派生出各种系统所需要的事件,可拓展性比较强。
而读写分离则确保了不会将视图与操作搅在一起增加混乱程度,可以让查询和命令自己干自己的。

具体的实现其实就是持久化日志+订阅顺序处理,持久化日志一般使用消息中间件来代替,但是要保证持久化这个特性,也就是消息可以被将来不同的消费者再次消费,例如Kafka。也可以做定时快照,然后基于快照点保存之后的日志(事件),之前的就可以归档了。

不是所有的场景和系统都需要这一套东西,它一般通常用于处理长流程的业务。
展开
2022 年 01 月 18 日 18:46
回复
用户头像
事件源架构会导致代码出现问题时,通过阅读静态代码难以排查。
“通过持久化事件而不是领域对象,克服了 CRUD 中出现的对象-关系阻抗不匹配问题。”这个并不能完全克服啊
2022 年 01 月 17 日 14:20
回复
我理解CQRS方式的话,查询需要单独设计一个用于查询的数据库或者类似方便OLAP的存储。事件源架构只是一种类似消息队列的功能,来实现更新的最终一致性。并不能用来业务查询。
2022 年 01 月 18 日 09:45
回复
用户头像
同配置,按照时间来确定哪个有效?这样会不会让查询变得复杂?
2022 年 01 月 16 日 18:20
回复
用户头像
事件源架构由于一直是追加变更,时间长了会出现存储量很大的问题吗?
2022 年 01 月 15 日 22:47
回复
用消息队列就可以了,追加的log也是会有保留期限的,问题不大
2022 年 01 月 16 日 15:27
回复
两者可以结合用吧,还得防止客户端重复消费等等
2022 年 01 月 17 日 08:53
回复
没有更多了
发现更多内容

ERP系统能帮你做些什么?ERP系统的部署类型哪个更适合你?

低代码小观

企业 企业管理 信息化管理 流程管理

盘盘 DevOps“衍生品”: DevSecOps、NoOps、AIOps

飞算全自动软件工程平台

企业采购堡垒机就上行云管家!云堡垒机杠杠的!

行云管家

云计算 网络安全 防火墙 堡垒机 云计算运维

一文读懂 OceanBase 数据库的SLog日志

OceanBase 数据库

oceanbase OceanBase 开源 OceanBase 社区版 OceanBase 数据库大赛

必须得会的汽车ECU研发基础--ECU是什么1

SOA开发者

Groovy入门常用语法

FunTester

Java 语法 测试开发 Groovy FunTester

云原生数据库TDSQL-C和传统主备方式数据库有什么区别?

腾讯云数据库

数据库 tdsql

出自阿里P8之手的这份微服务架构实践手册,为何能霸榜GitHub一周

进击的王小二

Java 架构 分布式 微服务

一个超火的SpringBoot +Vue实战项目,GitHub标星48K,文档视频贼全!

程序员知识圈

Java 程序员 面试 编程语言 项目源码

从敏捷开发到DevOps,殊途亦同归

力软.net/java开发平台

DevOps 敏捷开发

一文说清楚css3具有颠覆意义的2D转换效果

前端史塔克

CSS html css3 大前端 html/css

【Python自动化测试网站推荐】免费资源网址,帮你找到所有想要的资源!!

程序员阿沐

华为宣布启动“开源雨林”计划,与社区伙伴共迎开源挑战

这本笔记!仅需16个小时,让你像阿里P7一样掌握Spring源码解析

Java 架构 面试 程序人生 编程语言

kubernetes pod访问不了外网但是宿主机可以

ilinux

Android性能优化之Android 10+ dex2oat实践

字节跳动终端技术

字节跳动 移动开发 Android; 火山引擎

沈抚示范区·“华为云杯”2021全国AI大赛圆满落幕

华为云开发者社区

人工智能 华为云 modelarts AppCube AI大赛

太牛了!这份阿里P8整理的《Java核心神技》,简直把所有Java知识操作都写出来了!

程序员知识圈

Java 程序员 架构 面试 编程语言

北京博睿宏远数据科技股份有限公司声明

博睿数据

带你读Paper丨分析ViT尚存问题和相对应的解决方案

华为云开发者社区

论文阅读 华为云 Vision Transformer 卷积核

Redis和tdsql数据异地同步(迁移)案例

腾讯云数据库

数据库 tdsql

号角声响!联想图像发起“百家百试”项目第二期,诠释“真国货之光”

🚄【Redis基础指南】推荐给大家的「主从模式」+「缓存穿透」的学习小贴士(提炼优化)

浩宇天尚

redis 10月日更 Redis缓存穿透

解读世界互联网大会新品——智能运维2.0,管运提效再升级

浪潮云

云计算

腾讯云原生数据库 TDSQL-C荣获“云原生卓越技术提供商”奖项

腾讯云数据库

数据库 tdsql

8. 这篇博客,把python从数值到模块、到字典、到元组,真python入门复习教程通览

梦想橡皮擦

10月日更

「IM开源推荐」前微信技术专家打造,golang实现,一键部署,客户端SDK全平台支持,轻松替代IM云服务

OpenIM

报名|飞桨中国行- AI赋能软硬件产品创新

百度大脑

人工智能 百度 飞桨

TDSQL交易型分布式数据库背景分析

腾讯云数据库

数据库 tdsql

MyCAT、DRDS、TIDB、TDSQL、TBase 在实现分布式事务时的区别及其各自的优势?

腾讯云数据库

数据库 tdsql

从用户关系看产品发展

石云升

产品经理 产品思维 产品分析 10月日更

为什么要从CRUD转向事件源架构?-InfoQ