CQRS架构简介

本文探讨了CQRS架构如何避免在高并发场景下的资源竞争问题,通过实例分析秒杀活动,提出了Command排队和限制Command修改同一个聚合根的策略。文章还讨论了Command和Event的幂等处理,以及在数据库层面如何实现并发控制。通过对CommandStore和EventStore的性能瓶颈分析,提出了优化方案,强调了规划存储时的重点考虑点,包括内存形式的In-Memory架构。最后,总结了CQRS架构如何结合高并发原则提高性能。
摘要由CSDN通过智能技术生成



前不久,看到博客园一位园友写了一篇文章,其间的观念是,要想高功用,需求尽量:避开网络开支(IO),避开海量数据,避开资本抢夺。对于这3点,我觉得很有道理。所以也想谈一下,CQRS架构下是怎样完结高功用的。

对于CQRS(Command Query Responsibility Segration)架构,咱们应当不会陌生了。简略的说,即是一个体系,从架构上把它拆分为两部分:指令处理(写恳求)+查询处理(读恳求)。然后读写两头能够用不一样的架构完结,以完结CQ两头(即Command Side,简称C端;Query Side,简称Q端)的别离优化。CQRS作为一个读写别离思维的架构,在数据存储方面,没有做过多的束缚。所以,我觉得CQRS能够有不一样层次的完结,比方:

  1. CQ两头数据库同享,CQ两头只是在上层代码上别离;这种做法,带来的优点是能够让咱们的代码读写别离,十分好保护,且没有CQ两头的数据共同性疑问,由所以同享一个数据库的。我自个以为,这种架构很实用,既统筹了数据的强共同性,又能让代码好保护。
  2. CQ两头数据库和上层代码都别离,然后Q的数据由C端同步过来,通常是经过Domain Event进行同步。同步办法有两种,同步或异步,假设需求CQ两头的强共同性,则需求用同步;假设能承受CQ两头数据的终究共同性,则能够运用异步。选用这种办法的架构,自个觉得,C端应当选用Event Sourcing(简称ES)形式才有含义,不然即是自个给自个找费事。由于这么做你会发现会呈现冗余数据,同样的数据,在C端的db中有,而在Q端的db中也有。和上面榜首种做法对比,我想不到啥优点。而选用ES,则一切C端的最新数据悉数用Domain Event表达即可;而要查询显现用的数据,则从Q端的ReadDB(联系型数据库)查询即可。

我觉得要完结高功用,能够谈的东西还有许多。下面我想要点说说我想到的一些规划思路:

避开资本抢夺

秒杀活动的比方剖析

我觉得这是很首要的一点。啥是资本抢夺?我想即是多个线程一同修正同一个数据。就像阿里秒杀活动一样,秒杀开抢时,许多人一同抢一个商品,致使商品的库存会被并发更新减库存,这即是一个资本抢夺的比方。通常假设资本竞赛不激烈,那无所谓,不会影响功用;可是假设像秒杀这种场景,那db就会抗不住了。在秒杀这种场景下,许多线程需求一同更新同一条记载,进而致使MySQL内部许多线程堆积,对效劳功用、安稳性形成很大损伤。那怎样办呢?我记得阿里的丁奇写过一个共享,思路即是当MySQL的效劳端多个线程一同修正一条记载时,能够对这些修正恳求进行排队,然后对于InnoDB引擎层,即是串行的。这么排队后,不管上层运用发过来多少并行的修正同一行的恳求,对于MySQL Server端来说,内部老是会聪明的对同一行的修正恳求都排队处理;这么就能保证不会有并发发作,然后不会致使线程糟蹋堆积,致使数据库功用下降。这个计划能够见下图所示:

如上图所示,当许多恳求都要修正A记载时,MySQL Server内部会对这些恳求进行排队,然后一个个将对A的修正恳求提交到InnoDB引擎层。这么看似在排队,实践上会保证MySQL Server不会死掉,能够保证对外供给安稳的TPS。

可是,对于商品秒杀这个场景,还有优化的空间,即是Group Commit技能。Group Commit即是对多个恳求合并为一次操作进行处理。秒杀时,咱们都在购买这个商品,A买2件,B买3件,C买1件;本来咱们能够把A,B,C的这三个恳求合并为一次减库存操作,即是一次性减6件。这么,对于A,B,C的这三个恳求,在InnoDB层咱们只需求做一次减库存操作即可。假定咱们Group Commit的每一批的size是50,那即是能够将50个减操作合并为一次减操作,然后提交到InnoDB。这么,将大大进步秒杀场景下,商品减库存的TPS。可是这个Group Commit的每批巨细不是越大越好,而是要依据并发量以及效劳器的实践状况做测验来得到一个最优的值。经过Group Commit技能,依据丁奇的PPT,商品减库存的TPS功用从本来的1.5W进步到了8.5W。

从上面这个比方,咱们能够看到阿里是怎样在实践场景中,经过优化MySQL Server来完结高并发的商品减库存的。可是,这个技能通常人还真的不会!由于没多少人有才能去优化MySQL的效劳端,排队也不行,更甭说Group Commit了。这个功用并不是MySQL Server自带的,而是需求自个完结的。可是,这个思路我想咱们都能够学习。

CQRS(Command Query Responsibility Segration)架构,大家应该不会陌生了。简单的说,就是一个系统,从架构上把它拆分为两部分:命令处理(写请求)+查询处理(读请求)。然后读写两边可以用不同的架构实现,以实现CQ两端(即Command Side,简称C端;Query Side,简称Q端)的分别优化。CQRS作为一个读写分离思想的架构,在数据存储方面,没有做过多的约束。所以,我觉得CQRS可以有不同层次的实现,比如: 1.CQ两端数据库共享,CQ两端只是在上层代码上分离;这种做法,带来的好处是可以让我们的代码读写分离,更好维护,且没有CQ两端的数据一致性问题,因为是共享一个数据库的。我个人认为,这种架构很实用,既兼顾了数据的强一致性,又能让代码好维护。 2.CQ两端数据库和上层代码都分离,然后Q的数据由C端同步过来,一般是通过Domain Event进行同步。同步方式有两种,同步或异步,如果需要CQ两端的强一致性,则需要用同步;如果能接受CQ两端数据的最终一致性,则可以使用异步。采用这种方式的架构,个人觉得,C端应该采用Event Sourcing(简称ES)模式才有意义,否则就是自己给自己找麻烦。因为这样做你会发现会出现冗余数据,同样的数据,在C端的db中有,而在Q端的db中也有。和上面第一种做法相比,我想不到什么好处。而采用ES,则所有C端的最新数据全部用Domain Event表达即可;而要查询显示用的数据,则从Q端的ReadDB(关系型数据库)查询即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值