如何设计一个高并发系统

人人都开始聊高并发,高并发,那么所谓的高并发到底应该是啥,应该怎么理解这个高并发这个概念呢?这么说来就得要思考为啥会产生高并发?

简单来说,因为我们从传统的单体项目开始系统都是需要直接连接数据库的,而数据库支撑到每秒并发两三千的时候,基本就快到极限了。因此,当我们刚开始设计系统的时候,就是一个简单的单体项目直连数据库,并没考虑那么多,结果后期由于业务发展太快,有的时候并发流量过大系统扛不住压力然后就挂了。

这种情况下数据库挂掉是很正常的,每秒几千,甚至上万的并发直接打到数据库,必然会宕机,因为mysql根本就扛不住这么高的并发量啊。

 

所以为啥高并发这个名词这么火?就是因为现在互联网用户越来越多,很多互联网站点、系统承载的都是高并发请求,高峰期每秒并发量几千,都是很正常的。特别是在促销活动比如京东六一八,天猫双十一之类的,每秒并发几万几十万都有可能。

 

那么问题来了,面对如此之高的并发量,再加上原本已经如此之复杂的业务,怎么办呢,怎么设计一个能支撑高并发的系统呢?我们来简单聊聊:

(1)首先是系统拆分,我们可以将一个复杂的“大”系统拆分为多个子系统,可以用现在最流行的springcloud架构来做,然后对数据库按业务进行垂直拆分,让每个系统(服务)连一个数据库,这样的话相当于将原本一个大的库拆分成多个数据库,数据库压力就可以分摊到各个库,也就可以抗高并发了。

(2)然后就是缓存,缓存在高并发系统中几乎是必不可少的。因为大部分的高并发场景,都是读多写少,我们完全可以将访问量大的数据在写入数据库的时候同时在缓存里再写一份,然后读的时候直接走缓存就行了。常用的缓存像redis轻轻松松单机几万的并发没任何问题。另外真正的高并发系统一般是做多级缓存的,比如nginx缓存、redis缓存、jvm缓存等。所以你可以考虑在你的系统里对于那些需要承载主要读请求的场景,怎么使用缓存来抗高并发。

(3)使用MQ,这个也是毋庸置疑的,也是高并发必备组件,毕竟MQ的功能之一就是流量削峰。因为系统中仍然有可能还是会出现高并发写的场景,比如电商促销活动或者秒杀活动下,你不可能直接将所有的订单直接操作到数据库中吧。想想那一瞬间的下单量,那高并发绝对搞挂你的数据库,然后你的系统也就跟着挂了,而且这种写的数据肯定不能用redis来承载的,毕竟redis是用来做缓存的,缓存是有过期策略的,写满了还会被redis的内存淘汰机制给清理了(LRU),而且redis数据格式太简单了,也没有标准的事务支持。所以总的来说还是得用mysql。那么怎么解决这个问题呢?这个时候MQ就派上用场了啊,我们直接将大量的写请求(比如下单数据)写入MQ中,依次排队等候慢慢消费就行啦,我们只需要控制从MQ中每秒消费的请求控制在mysql承载范围之内就ok了,比如mysql每秒最多支撑2000并发,那你就每秒从MQ从消费小于2000的请求就行了。所以你得考虑你的系统里,那些承载复杂写业务逻辑的场景里,如何用MQ来异步写,提升并发性。MQ单机抗几万并发也是ok的,而且是高可用的不会造成数据丢失。

(4)分库分表,这个其实在第(1)点的时候就已经说明了,数据库层面我们可以将一个数据库拆分为多个库,用来抗更高的并发;然后将一个表拆分为多个表,每个表的数据量保持少一点,提高sql的性能。

(5)读写分离,这个也是针对数据库层面的,因为可能大部分时候数据库也是读多写少,可以搞个主从架构主库写入,从库读取,搞一个读写分离,避免所有请求直接打到一个数据库中,分摊单库的压力。读流量太多的时候,还可以加更多的从库。

(6)可以考虑使用Elasticsearch。毕竟es是分布式的,扩展也方便,分布式天然就可以支撑高并发。针对全文搜索类、聚合类、统计类的操作,可以考虑用es来承载。

借图:

如何设计一个高并发系统_第1张图片

 

上面介绍的,基本上一般是高并发系统都需要涉及到的几个方面。

 

其实,像MQ、Redis、Elasticsearch这种一门或者几门技术的基本使用对一般开发者来说都不是什么难事,难得是怎么把这些技术结合起来,一步步架构、设计整合到我们的具体的业务场景中,形成一个分布式架构系统,让我们的系统能真正支持高并发。

 

关注微信公众号“虾米聊吧”,一起学习,一起进步!

微信扫描二维码,关注我的公众号

你可能感兴趣的:(架构)