处理高并发的六种方法
1:系统拆分
将一个系统拆分为多个子系统,用dubbo来搞。然后每个系统连一个数据库,这样本来就一个库,现在多个数据库,这样就可以抗高并发。
将一个系统进行功能拆分,如现在流行的微服务,每个服务连接的数据库分开,分开部署。这样可以将压力进行拆分,缓解因为网络和数据库导致的高并发。
2:缓存
必须得用缓存。大部分的高并发场景,都是读多写少,那你完全可以在数据库和缓存里都写一份,然后读的时候大量走缓存不就得了。毕竟人家redis轻轻松松单机几万的并发啊。没问题的。所以你可以考虑虑考虑你的项目里,那些承载主要请求读场景,怎么用缓存来抗高并发。
大部分场景下,都是查询多余插入更新,也就是读多写少。因此设计时对常用的查询内容必须进行缓存,查询时先查缓存,再查数据库;更新时也要更新缓存;
redis 单机支持几万的并发。项目设计时针对那些承载主要请求的读场景,怎么用缓存来抗高并发。
3:MQ(消息队列)
必须得用MQ。可能你还是会出现高并发写的场景,比如说一个业务操作里要频繁搞数据库几十次,增删改增删改,疯了。那高并发绝对搞挂你的系统,人家是缓存你要是用redis来承载写那肯定不行,数据随时就被LRU(淘汰掉最不经常使用的)了,数据格式还无比简单,没有事务支持。所以该用mysql还得用mysql啊。那你咋办?用MQ吧,大量的写请求灌入MQ里,排队慢慢玩儿,后边系统消费后慢慢写,控制在mysql承载范围之内。所以你得考虑考虑你的项目里,那些承载复杂写业务逻辑的场景里,如何用MQ来异步写,提升并发性。MQ单机抗几万并发也是ok的。
再考虑高并发写的场景,比如一个业务操作要数据库操作几十次,增删改增删改,在普通环境下不会有问题,但是如果高并发绝对会出现问题;
如通讯分析项目,话单导入时多线程同时导入。如果多个用户都同时导入,会有多个导入任务,几十几百甚至启动上千的线程跑。也会导致系统出现问题;
可以将大量的写请求灌入 MQ 里,进行排队,后边系统慢慢写,控制在数据库承载范围之内。MQ 单机支持几万并发,所以设计系统时,对应承载复杂写业务逻辑的场景里,如何用 MQ 来异步写,提升并发性。
缺点:
· 系统可用性降低-外部依赖越多,越容易出现问题
· 系统复杂度提高-需要处理重复消费和丢失的问题
· 一致性问题-由于是异步需要保证数据的完整
Kafka、ActiveMQ、RabbitMQ、RocketMQ 优缺点
4:分库分表
可能到了最后数据库层面还是免不了抗高并发的要求,好吧,那么就将一个数据库拆分为多个库,多个库来抗更高的并发;然后将一个表拆分为多个表,每个表的数据量保持少一点,提高sql表的性能。
5:读写分离
这个就是说大部分时候数据库可能也是读多写少,没必要所有请求都集中在一个库上吧,可以搞个主从架构,主库写入,从库读取,搞一个读写分离。读流量太多的时候,还可以加更多的从库。
6:搜索
SolrCloud(solr 云)是Solr提供的分布式搜索方案,可以解决海量数据的 分布式全文检索,因为搭建了集群,因此具备高可用的特性,同时对数据进行主从备份,避免了单点故障问题。可以做到数据的快速恢复。并且可以动态地添加新的节点,再对数据进行平衡,可以做到负载均衡:
如Elasticsearch,简称 es。es 是分布式的,可以随便扩容,分布式天然就可以支撑高并发,因为可以扩容加机器来扛更高的并发。一些比较简单的查询、统计类的操作,可以考虑用 es 来承载,还有一些全文搜索类的操作,也可以用 es 来承载
项目设计的思考
在实际设计项目中,做高并发要远比上面提到的点要复杂的多。需要考虑:
哪些需要分库分表,哪些不需要分库分表,单库单表跟分库分表如何 join,哪些数据要放到缓存里去,放哪些数据才可以扛住高并发的请求
需要完成对一个复杂业务系统的分析之后,然后逐步逐步的加入高并发的系统架构的改造