设计一个高并发系统可以从下面这些角度来考虑。
所谓设计高并发系统,就是设计一个系统,保证它整体可用的同时,能够处理很高的并发用户请求,能够承受很大的流量冲击。
我们要设计高并发的系统,那就需要处理好一些常见的系统瓶颈问题,如内存不足、磁盘空间不足,连接数不够,网络宽带不够等等,以应对突发的流量洪峰。
1分而治之,横向扩展
这个如何理解呢?
如果应用就部署在一台服务器上面,那么能抗住的流量请求是非常有限的,并且存在单点风险,如果挂了,服务就不可以用了。
因此将项目部署在多台服务器上面,用nginx进行负载均衡,把流量分开,让每个服务器都承担一部分的并发和流量,来提升并发能力。
2微服务拆分
把一个单体应用按功能拆分为多个服务模块,当一个服务挂了的时候,其他服务还是可以运行的。
3分库分表
比如双十一,业务量直接爆了,mysql单机磁盘量会撑爆。
可以将数据库拆分为多个数据库,来抗住高并发的毒打。
如果一个表里面的数据达到了千万级别,就需要进行分表了。
这个中间还有很多的细节需要学习,比如分表之后如何保证数据的一致性,ID是怎么做的。
使用缓存
这个也是最简单的,很多请求其实都是get请求,没有修改对应的数据,可以将热点数据缓存到磁盘中去。这样每次访问的时候都会去磁盘中寻找,如果缓存中有,那么就直接返回,如果没有就需要查询数据库。
使用Redis缓存也会有三个问题:缓存击穿、缓存雪崩、缓存穿透。
缓存击穿:当热点数据过期的时候,大量的请求发过来,全部会压倒数据库,
缓存穿透:当redis里面没有数据的时候,就会到数据库中找数据,当出现大量这种请求的时候,接口的访问全部穿过Redis访问数据库,而数据库中没有这些数据,所以这种现在被称为缓存穿透。
缓存雪崩:大面积的数据过期,然后大量并发的查询穿透Redis冲击到数据库上面,此时数据库的压力会变大,相比于缓存击穿,雪崩更容易发生。
限流
异步Rocketmq
用mq来进行异步处理。
设计一个高并发的系统,需要在恰当的场景使用异步。如何使用异步呢?后端可以借用消息队列实现。比如在海量秒杀请求过来时,先放到消息队列中,快速相应用户,告诉用户请求正在处理中,这样就可以释放资源来处理更多的请求。秒杀请求处理完后,通知用户秒杀抢购成功或者失败。
ElasticSearch
Elasticsearch,一般搜索功能都会用到它。它是一个分布式、高扩展、高实时的搜索与数据分析引擎,简称为ES。
我们在聊高并发,为啥聊到ES呢? 因为ES可以扩容方便,天然支撑高并发。当数据量大的时候,不用动不动就加机器扩容,分库等等,可以考虑用ES来支持简单的查询搜索、统计类的操作。