关于高并发架构
自己当然没有涉及到大量的高并发场景,摘抄一下,扩充知识。
高并发经常发生在有大量的活跃的用户,用户高聚集的业务场景中,像秒杀,抢红包等。为了流畅的运行业务和好的用户体验,我们需要预估达到的并发量,来涉及场景。
1.服务器架构
服务器从业务发展的初期的相对单一到集群,再到分布式服务,高并发的场景肯定少不了服务器的良好架构,需要有负载均衡,数据库的主从结构,nosql的缓存也需要主从集群,图片有专门的服务器,静态文件需要上传CDN,这些都是服务能够良好运行的基础架构。服务器这块是需要运维人员参与的。大致是:
服务器:
负载均衡(nginx等),资源监控,分布式....
数据库:
主从分离,集群 ,表结构优化,索引优化。
nosql:
主从分离,集群,redis,memcahce,mongodb
cdn:
html,css,js,image
2.实战方案
(1)通用方案:日用户流量大,但是比较分散,偶尔会有用户高聚集的情况
场景:用户签到,用户中心,用户订单...
用户->负载均衡->服务器集群->redis主从集群->(同步缓存)DB主从集群。
介绍:一般来说这些业务的用户量不会高聚集,这些业务相关的表都是大数据的表,多是查询操作,所以我们尽量要减少直接命中数据库的查询,优先读取缓存,如果缓存不存在,再去DB查询,并缓存结果。更新用户相关的缓存需要分布式的存贮,比如使用用户ID进行hash分组,把用户分布到不同的缓存中去,这样一个缓存集合的总量不会太大,不会影响查询的效率!
用户签到获取积分:计算出用户分布的key,redis hash中查找用户今日的签到数据,有返回签到信息,无从DB查询今日是否签到,如果有,就把签到信息同步redis缓存,如果没有,执行签到的逻辑,添加签到的积分(这一整个操作是DB事务),
用户订单:这里只缓存用户第一页订单(40条数据),一般也只看第一页,用户访问订单列表,第一页则读取缓存,不是则DB,缓存信息。
以上只是相对简单的高并发的架构,并发量小的话可以很好的支持,如果并发量过大,架构也应该进行不断的优化,每个服务都有自己的并发的架构,自己的均衡服务器,分布式的数据库,nosql主从集群。
(2)消息队列:秒杀等活动业务,用户在瞬间涌入产生高并发请求。
场景:定时领取红包
用户->负载均衡->服务器集群->redis主从集群-push(消息队列)->pop(数据库执行)->缓存redis
秒杀活动在指定时间会有大量的用户涌入,DB瞬间遭到一记暴击,hold不住就会宕机,像这种情况,并不是只有查询,还会有写入的情况,通用的方案无法支撑,设计这块业务我们应该考虑消息队列,然后写个多线程的程序去消耗队列,给队列中的用户发红包。
定时领取红包:一般习惯使用redis的list,当用户参与活动的时候,将用户信息push到队列中,然后执行pop操作,进行发放红包,这样可以支持高并发业务的用户进行正常的参与活动。
PS:通过使用消息队列可以做很多的服务,如:定时发送短信(sset),发送时间错作为排序的依据,
3.一级缓存
高并发的请求连接缓存的服务器如果超过缓存服务器的请求连接量,部分用户就会出现连接超时,拿不到数据的情况,这时候出现一级缓存的方案,是使用站点的服务器去缓存数据,注意只缓存部分请求量大的数据,并且缓存的数据量要得到控制,不能影响应用程序的正常运行,要设置秒单位的过期时间,目的是当有高并发的请求的时候可以让数据去命中一级缓存,减少nosql数据库的压力。
场景:App首屏的商品数据的接口,数据是公共的,而且不会频繁的更新,像这种请求量大的接口就可以加入一级缓存。
4.静态化数据
对于更新频繁度不高,并且数据允许短时间延迟,可以通过数据静态化城JSON,XML等上传CDN,在拉数据的时候优先到CDN去拉,然后走缓存,DB。