从读写分离到CQRS,张大胖是如何解决性能问题的?

DDD-CQRS能解什么问题 背景 在DDD代码实践过程出现一些看起来很别扭的实现 为了查询,领域聚合根无限扩大 如商品详情页聚合根 public class BrandAggr { /** * 唯一标识 */ private Long id; /** * 商品简介 */ private ItemInfoVal brandInfoVa... 阅读详情

1不堪重负的数据库


张大胖公司的数据库已经不堪重负了。

这个系统最早是两个实习生写的, 按照最初的设计,只是内部用户玩的, 大家可以把一些闲置不用的东西放在上面做交换,  仅此而已,后来为了在互联网的大潮中赚点钱,又包裹上了一层Web的外衣, 让外界也可以访问。

大家没有想到互联网威力如此巨大, 用户量会如此之多, 他们系统使用的Mysql数据库很快就撑不住了。

作为技术负责人的张大胖早已经向老大申请了一笔费用, 专门买了一个高性能的服务器来应对, 但是汹涌而来的用户很快就把高性能给吃得连渣都不剩。

张大胖忧心忡忡: “老大,怎么办? ”

老大也是技术出身,反问道: “你分析过为什么数据库压力这么大吗? ”

“无非就是读写量太大了,尤其是有一些非常复杂的查询, 比如最近24小时最热门的物品之类,需要写很复杂的SQL, 运行起来实在太慢了。”

“我记得咱们俩聊过读写分离啊, 怎么不试一试?”

“老大啊, 你不知道,这实在是不好弄啊, 为了实现读写分离, 得把数据库拆分成master库和slave库, 还比较简单, 但是我们的系统代码也得改啊, 写数据的时候用master 库, 读数据的时候用slave库, 你知道我们这是上个世纪开发的系统,典型的遗留代码,  改动起来太麻烦了。”

老大说:“那也得改啊, 你要知道现在这个系统可是咱们公司最大的收入来源了。 你们要是不想改,就退下来,我只好去找李小疯去做了”

张大胖向来瞧不起马屁精李小疯,技术不咋地,升的到挺快,一起进公司的, 现在已经比自己高一级了。

张大胖赶紧说:“ 别别, 还是我来”

张大胖带着几个弟兄和遗留代码奋战了几个月,  工作量不亚于一次重写。 张大胖深深地体会到,别看现有代码很烂, 但是经过无数人的修补,勉强能工作。 现在自己从头写一遍,出的问题更多,很多小细节考虑不到,被测出了无数Bug。

不过好处也是巨大的,这次重写,理清了业务, 实现了读写分离,还把缓存也用上了, 最后熬了两天两夜,新系统终于上线了。

张大胖想着好日子就要开始了,崭新的代码, 崭新的系统,应该可以撑一段时间。

2复杂的查询

可是新系统上线了一周后,问题又出现了,这次的问题主要集中在一些复杂的SQL查询上,这些SQL查询最要命的得有几十行! 严重地拖累了数据库 !

张大胖找来DBA 小梁过来做优化,小梁看了半天说: “没辙, 你们的业务太复杂了, 你看看有这么多表在做Join,怎么可能快呢?”

张大胖说:“这没办法啊,数据库就是这么设计的啊, 你懂的,无论如何也得满足第一范式吧。 要不这样,你给我们创建一个视图(View) 吧, 把这个复杂的查询给封装起来, 这样我们使用起来就简单了”

“那也是换汤不换药啊, 实际的查询还在, 没有本质的改变,  照样还是慢。”

“唉,这可怎么办, 我们有20多个复杂查询,怎么才能提高速度呢?”

小梁说: “你看看这个超级复杂的查询, 不就是为了获得过去24小时的热门产品吗,要是有个表单独存放就好了 hot_products(id, name, desc, total_sold) , 这样以来一条简单的SQL就搞定”

小梁的话启发了张大胖: 实际上,一套单一的数据库表 对于报表、搜索、事务等不同的行为是不适当的 !

现在复杂的数据查询和简单的数据修改利用的就是同一套领域模型和数据库表, 现在的数据库表主要是为了新增、修改数据而设计的, 对于复杂的查询并不友好。  我们能不能单独的建一套数据库,专门应对查询呢?

0?wx_fmt=png

有了这个专门的查询库, 用户在界面上发起查询的时候处理起来非常简单, 一条SQL就搞定,甚至都不用通过业务领域层,换句话说数据库模型和展示层是对应的!  再也不用像原来那样从原始数据库表中得到数据,转化成领域对象, 然后再转化成展示层对象, 实在是太麻烦了 !

0?wx_fmt=gif

但是这个专门的查询库该如何更新呢? 更重要的是能不能忍受数据的延迟呢?

3CQRS

张大胖把自己的想法和苦恼给老大讲了下。

老大拍了拍他的肩膀: “看来你小子开窍了啊, 想得挺深入的, 从业务上看数据的延迟可以忍受,比如过去24小时的热门产品,一点点过时的数据对用户不会产生重大的影响。只要你能达到最终一致就可以了。”

“那我们该怎么更新这个专门的查询库呢?”

“我最近在看一个叫做CQRS的东西”  老大说  “ 你遇到的这个问题可以用同样的思路来解决下”

“什么是CQRS ? ”

"Command Query Responsibility Segregation,就是命令(增删改)和查询的责任分离, 你看看这个图"

0?wx_fmt=gif

0?wx_fmt=png

“这和我刚才的图差不多啊” 张大胖说

“所以说思路是一致的嘛, 在CQRS中, 强调的是读(Query)和写(Command) 的分离 ,  它背后的理念是用户读到的数据通常是过时的,比如过去24小时最火的产品, 既然如此, 为什么还要从数据库中读取一遍,转化为领域模型,DTO, VO, 最后在UI层展示呢? 何不直接一点,干脆为‘读’专门建立一个直接的数据源呢? 这新的数据源不一定是关系数据库,可以是Cache ,可以直接存储为xml/json数据, 只要界面查询起来方便即可。 ”

“是,最早我也是这么想的,那这个Event是怎么回事?”

“Event 就是事件喽,例如有人下了一个订单, 导致某个产品已经卖出, 这个时候就可以发布一个产品已经卖出(ProductSold)的事件 , 其中包含产品的ID, 价格,卖出时间等属性, 这样的事件被处理以后,可以变成任意的Read Model,例如过去24小时最火的产品 。”

“奥,原来是这么玩的啊, 通过事件机制把同步变成异步 ”  张大胖说 “ 还有一个问题,如果我们用CQRS, 难道我们的应用需要把所有的Command 和Query完全分开吗, 查询都通过新的数据源?  可是很多查询很简单,直接使用关系数据库就够了啊。 ”

“不,不要把摊子铺得太大, 引入一种新的技术也是需要付出代价的,我们把同步操作变成了异步的操作, 得有良好的事件处理机制才可以。 所以先用这种思路把你的当前问题,也就是复杂查询的问题解决掉吧!” 老大最后拍了板。

(完)

你看到的只是冰山一角, 更多精彩文章,请移步《码农翻身2016文章精华》或者《码农翻身2017上半年文章精华》

有心得想和大家分享? 欢迎投稿 ! 我的联系方式:微信:liuxinlehan  QQ: 3340792577


码农翻身

用故事讲述技术

0.jpeg

DDD里面的CQRS到底是什么? 开篇 随着业务不断发展,软件系统的架构也越来越复杂,但无论多复杂的业务最终在系统中实现的时候,无非是读写操作。用户根据业务规则写入商业数据,再根据查询规则获取想要的结果。通常而言我们会讲这些读写的数据放到一个数据库中保存,通过一套模型对其进行读写操作。而在大型系统中往往查询操作远远多于写入操作,于是就有了读写分离的思想,将读操作和写操作的模型分开定义并且提供不同的通道供用户使用。CQRS(Command-Query Responsibility Segregation)就是基于这一思想提供的一种模式读.. 阅读详情

相关推荐

大数据架构中的CQRS模式:读写分离实践

随着互联网业务规模爆炸式增长,传统单体架构的读写混合处理模式在面对亿级数据量和百万级并发时,暴露出严重的性能瓶颈。典型场景如电商平台的订单查询(读多写少)、社交平台的动态流处理(写扩散读),传统数据库的ACID强一致性模型难以平衡性能与可用性。本文聚焦CQRS模式在大数据架构中的落地实践CQRS核心原理与架构设计读写分离的技术实现路径事件溯源与最终一致性的结合分布式系统中的数据同步与冲突解决实际案例的性能优化经验核心概念:解析CQRS的本质与架构要素。

AI 原生应用开发的博客 822

一个著名的任务调度系统是怎么设计的?

实习生张大胖这是个代码写得很烂的电商系统,只要运行一段时间,服务器就会出现Out Of Memory。别人都忙得四脚朝天,于是实习生张大胖被抓了壮丁去研究为什么会出现OO...

码农翻身 2155

Ubuntu 24.04.3 LTS 安装 OpenClaw 图文版

OpenClow安装指南

qq_17204557的博客 2554

CQRS-一种读写分离的数据处理模式

译者按: 本文是翻译自Martin Fowler的一篇博客。 老马同志向来是我所敬仰的大师级人物,现在的“微服务”这个词就是从老马同志的博客开始火起来的。原文链接CQRSMartin Fowler 14 July 2011CQRS指的是命令查询职责分离模式,最早我听 Greg Young 提起过,该模式的核心思想是把数据的读操作和写操作分离开来。在某些场景下这种模式很有用,但 CQRS 也会增加

熊出没注意 2772

本地部署开源视频会议解决方案 Jitsi Meet 并实现外网访问

Jitsi Meet 是一款基于 WebRTC 技术的开源视频会议解决方案,它允许用户通过互联网进行高质量的视频通话、语音通话和文本聊天,非常适合用于在线教育、远程办公、团队协作等场景。本文将详细介绍如何利用 Docker 在本地部署 Jitsi Meet 并结合路由侠实现外网访问本地部署的 Jitsi Meet。

lyxnwct的博客 1946

构建可编程记忆系统:OpenClaw-SuperMemory本地部署与智能知识管理实战

在信息过载的时代,高效的知识管理与智能检索成为技术从业者的核心需求。向量数据库与嵌入模型技术通过将文本转化为高维向量,实现了基于语义相似度的智能搜索,突破了传统关键词匹配的局限。这项技术的核心价值在于将静态存储的信息转化为可动态查询和计算的知识资产,极大地提升了信息调用的准确性和效率。其应用场景广泛,从个人笔记管理、对话历史归档到企业知识库构建都能发挥关键作用。本文聚焦于开源项目OpenClaw-SuperMemory,它正是基于这一技术栈,通过本地化部署实现了可编程记忆系统的构建。项目集成了ChromaD

weixin_42525482的博客 320

《MySQL实战45讲》——学习笔记28 “读写分离/主从延迟的解决方案/GTID“

读写分离架构下,发生主从延迟时,可能出现主库已落表而从库因为主从延迟还查不到最新数据的问题;这种"在从库上读到过期数据"的现象,在本文里暂且称之为"过期读"; 本篇主要介绍从业务角度和MySQL架构角度处理主从延迟问题的一些方案,包括:读写分离架构、强制路由主库方案、延迟请求从库方案、设计库表时采用分库分表方案、判断是否存在主从延迟方案、GTID的概念,以及判断指定的事务是否已经在从库完成执行的方案(等主库位点/GTID方案);

娜娜米的博客 1401

mac安全干净卸载Anaconda3

主要原因是python命令没有映射到已经安装的python版本上,则需要添加。修改~/.bash_profile文件,将anaconda相关删除。现在想卸载Anaconda,恢复使用mac系统自带的Python。最后在mac的应用目录删除Anaconda。查看所有版本的python所在安装目录。或者不使用软连接映射,也可使用。再次查看python映射。查看python版本。建立软连接,添加映射。

buyue 5964

数据库读写分离这个坑,让刚入职的我一脸懵逼!

今天分享一下以前入职现在公司第一次发布项目遇到的一个问题,一个数据库读写分离的坑。前言事情是这样的,刚入职的时候接到了这样的一个业务需求:每个支付通道支付失败的时候都会返回特定的错误码,业务内部需要将通道特定的错误码转义成内部的错误码,这样对外就可以统一返回我们自己的错误码。这个需求其实不难,当时设计的系统架构如下:新增规则的流程简单分为三步:业务人员通过管理后台新增映射规则数据库新增、修改这条映...

十指波课堂的博客 983

【腹腔镜数据集】Cholec80+CholecSeg8k2020+Endoscapes2024

计算机辅助手术的发展旨在提高手术的正确性和安全性。然而,研究人员和工程师却面临着开发和训练更好算法所需的注释数据有限的问题。因此,同步定位与建图(SLAM)等基础算法的发展受到限制。基于Cholec80数据集,从Cholec80中的17个视频片段中提取了8,080个腹腔镜胆囊切除术图像帧,对图像进行注释并向公众发布。该数据集名为 CholecSeg8K。这些图像中的每一个都以十三个类别的像素级注释,这些类别通常在腹腔镜胆囊切除术中发现。

Toky_min的博客 2020

数据中心机房设备标签规范建议

机房的维护工作中,标识管理是极其重要的一部分,从基本的线缆上跳接信息的标识,到设备、机柜标识规范的实施,不同程度的体现了标识管理的重要作用。本规范适用于机房主设备、线缆、机柜(含PDU插排)、仪器仪表、动力配套设备(各类空调、消防设备、配电柜、UPS等设备)、网络口、电源插座口的标签、标识规定。动力设备的设备编号、设备名称、生产厂商及厂商技术支持热线、设备型号、设备序列号、设备使用部门、设备责任人、设备启用时间及设备保修年限、条形码。各类标签、标识可根据设备和机柜的尺寸、大小进行调整。

有地气的强弱电小圈子 3527

一周技术学习笔记(第62期)-CQRS是”有点不同“的读写分离

对数据的操作一共就四种。图自https://time.geekbang.org/dailylesson/detail/100056986我们把这四种操作,又划分为两类,读和写。为了提升对数据库的性能,我们又做了读写分离。上面这个图是我们最为熟悉的读写分离场景了,另外我们也熟悉了这样的方法有两个不好地方。1、写库有单点故障问题。2、数据库同步有延迟。TIP:读写分离,更主要...

新栋BOOK 1128

值得苦练的100道Python经典练手题(全网最全,附详细答案,建议收藏)

这100道Python练习题涵盖了从基础语法到高级算法、从数据库操作到Web开发的各个方面,是备考数据库系统工程师的绝佳素材。建议按照章节顺序逐一练习,遇到难点可反复钻研,真正掌握每一道题背后的知识点。通过这些练习,不仅能提升Python编程能力,还能加深对数据库系统原理的理解,为考试和实际工作打下坚实基础。

yue_yun_的博客 9396

从读写分离到 CQRS,张大胖是如何解决性能问题的?

转自:https://mp.weixin.qq.com/s/rpiYZkxiLKa77OFw8XaBwA 不堪重负的数据库 张大胖公司的数据库已经不堪重负了。 这个系统最早是两个实习生写的, 按照最初的设计,只是内部用户玩的, 大家可以把一些闲置不用的东西放在上面做交换, 仅此而已,后来为了在互联网的大潮中赚点钱,又包裹上了一层Web的外衣, 让外界也可以访问。 ...

weixin_34195142的博客 95

ubuntu20 安装px4、mavros、QGroundControl

首先安装一下ant,否则没法运行,同时因20.04的缺少动态库libawt_xawt.so无法被Java8给调用,我的解决办法是去18.04把18.04的相同路径下的动态库libawt_xawt.so移动到20.04的/usr/lib/jvm/java-11-openjdk-amd64/lib/路径中。用rosdepc的时候,你得确保你用的是鱼香ROS的提供的ROS安装方法,否则是没有rosdepc的。make px4_sitl gazebo之前,可以安装一下gazebo的 模型。二、安装MAVROS。

qq_58060770的博客 3349

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

浅谈CQRS

Greg Young 在 2010 年创造了CQRS(Command Query Responsibility Segregation)架构模式。本文简单的介绍了CQRS是什么,为啥要用,以及优缺点。

zhh763984017的博客 4956

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

革命性架构:CQRS模式彻底解决读写分离难题

在现代分布式系统设计中,数据读写操作的高效处理一直是开发者面临的核心挑战。**Command Query Responsibility Segregation (CQRS)** 作为一种革命性的架构模式,通过将系统的命令操作(写操作)与查询操作(读操作)分离,彻底解决了传统架构中读写耦合导致的性能瓶颈问题。本文将深入解析CQRS模式的核心原理、实施步骤及其在实际系统中的应用价值。 ## 什么是C

gitblog_01071的博客 833

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

程序员除了会 CRUD 之外,还应该知道什么叫 CQRS!

作者 |倪升武 责编 | 郭 芮 今天主要跟大家分享一下什么是 CQRS,以及在项目中如何去使用。 CRUD系统 我们平常最熟悉的就是三层架构,通常都是通过数据访问层来修改或者查询数据,一般修改和查询使用的是相同的实体。然后通过业务层来处理业务逻辑,将处理结果封装成DTO对象返回给控制层,再通过前端渲染。反之亦然。 这里基本上是围绕关系数据库构建而成的“...

优快云资讯 8848

Java 架构 09:CQRS 架构(读写分离)在 Java 中的实现

本文介绍了CQRS架构在Java中的实现,通过读写分离解决传统CRUD架构的局限性。主要内容包括: CQRS核心思想:将系统分为写模型(处理命令修改状态)和读模型(处理查询返回数据),实现职责分离、独立优化和扩展。 适用场景:适用于读写负载差异大、查询逻辑复杂、高并发写入低延迟读取等场景,不推荐简单CRUD应用使用。 技术栈:基于Spring Boot 3 + Java 17,结合Kafka实现事件驱动架构,使用MapStruct进行DTO转换。 实战案例:实现电商订单系统,包含领域事件定义、写模型(JPA

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

为什么需要CQRS,它能解决什么问题?

CQRS(Command Query Responsibility Segregation,命令查询职责分离)是一种架构模式,它通过将修改操作(命令,Command)与查询操作(查询,Query)分开,使用不同的模型来分别处理这两类操作,从而实现命令与查询的分离。命令应用服务(Command Application Service):负责处理写操作,如创建、更新和删除。查询应用服务(Query Application Service):负责处理读操作,包括数据查询和展示。

m0_50180963的博客 748

【Java开发300个实用技巧】231.CQRS读写分离架构

CQRS(命令查询责任分离)架构通过将数据库的读写操作分离,有效提升系统性能,特别适用于高并发场景。核心思想是将业务逻辑划分为命令(写操作)和查询(读操作),避免读写冲突。实施步骤包括业务逻辑切分、物理隔离存储和同步机制搭建。数据同步中需注意事件丢失、顺序错乱和数据延迟等问题,通过双重写入、版本号控制和查询补偿等策略解决。性能优化可通过缓存策略、索引优化、异步处理和分库分表实现。CQRS适用于电商、社交平台和物联网等场景,但需避免在小体量系统中过度设计。

782

CQRS架构

命令查询的责任分离Command Query Responsibility Segregation (简称CQRS)模式是一种架构体系模式,能够使改变模型的状态的命令和模型状态的查询实现分离。这属于DDD应用领域的一个模式,为了使得项目逻辑更加清晰,便于对不同部分进行针对性的优化。 一. 背景问题 在以前的管理系统中,命令(Command,通常用来更新数据,操作DB和查询(Query)通常使用...

zhoxing 9409

CQRS模式:pybind11读写分离架构深度解析

CQRS(Command Query Responsibility Segregation,命令查询职责分离)是一种架构模式,它将数据修改操作(命令)和数据查询操作(查询)分离到不同的模型中。在C++与Python混合开发场景中,pybind11作为强大的绑定库,为CQRS模式的实现提供了理想的技术基础。 本文将深入探讨如何在pybind11项目中实现CQRS架构,通过读写分离提升系统性能、可维...

gitblog_00709的博客 877

Web 架构之CQRS模式:读写分离的进阶实践

在现代Web应用开发中,随着数据量的增长和业务复杂度的提升,传统的读写一体架构逐渐暴露出性能瓶颈和可维护性问题。CQRS(Command Query Responsibility Segregation,命令查询职责分离)模式作为一种读写分离的进阶实践,为解决这些问题提供了有效的方案。本文将深入探讨CQRS模式的原理、优势、实现方式以及在Web架构中的应用场景,并通过实际案例展示其具体实践。CQRS模式作为一种读写分离的进阶实践,为现代Web应用开发提供了有效的解决方案。

懂搬砖 1046
上一篇: 工作6年,半路出家到CTO
下一篇: 对自己狠一点,开始写作吧
码农翻身
码农翻身 《码农翻身》作者 《码农翻身》作者
博客等级 码龄8年 3万+粉丝 1084原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值