Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说高并发多级缓存架构解决方案:OpenResty+lua+redis+mq,希望能够帮助你!!!。
在我们日常工作生活中,高并发场景十分的常见,最典型的莫过于“618”、“双十一”等大促活动,而应对高并发最有效的手段莫过于分布式缓存,缓存不仅仅是查询数据这么简单,还可以在限流、队列削峰、高速读写、分布式锁等场景发挥重大作用,可以说缓存是解决高并发的一大利器。本文只对架构体系进行分析,具体细节不做过多阐述。
我们从一次用户的请求为例,分析一下上图的架构:
1、浏览器可以做本地缓存,可以缓存html页面和其他静态资源,防止用户频繁刷新对后端造成巨大影响
2、lvs可以记录不同协议以及缓存不同用户的请求链路
3、Nginx可以做HTML缓存配置,Nginx本身也可以缓存数据
4、lua脚本可以直接查询数据库绕开我们的java应用,极大的提高了查询效率,并发效率大大提升
5、redis可以缓存我们数据库的数据,搭建Redis sentinel或者Redis cluster,也可以提高我们并发效率
6、集成canal实时同步数据库增量数据到Redis
我们都知道受疫情影响口罩特别是在疫情初期用户查询量特别大,这种场合我们使用多级缓存,将大大提高我们的效率。我们以此为案例进行热点数据进行分析,请看下图:
这是我们比较常用的一种架构,用户查询口罩商品,经过nginx、tomcat,然后我们判断Redis中是否有相关数据如果存在返回数据,如果不存在到数据库中查询,然后将数据缓存到Redis,一般情况下是没有问题的,但是遇到突发情况类似口罩这种商品,我们的系统就可能有点力不从心了,甚至系统崩溃。那么我们使用多级缓存能够大大解决这种问题。
上面是我们使用openresty+lua的多级缓存体系,openresty我们可以理解为Nginx的加强版,它允许我们在Nginx中使用lua脚本,lua在高并发条件下表现特别突出。我们根据此架构简单分析一下查询口罩这个热门商品的流程:
1、用户查询口罩,执行lua脚本
2、lua判断nginx缓存中是否存在数据,存在直接返回数据
3、假设nginx缓存中不存在数据,查询Redis是否存在,存在返回数据,并将数据缓存到nginx中
4、如果Redis也不存在数据,查询数据库,通过lua将数据缓存到Redis和nginx中,并返回数据
通过此流程我们可以发现,如果nginx缓存中存在数据会直接返回数据,大大提高我们的响应速度,而单机nginx的并发在10k左右,大大提高系统的处理能力。
红包是现在非常常见的一种促销方式,具有以下特点:
1、并发量大
2、红包并非一下发完,有时需要分时间段发放
3、每个用户存在概率问题和上限问题,用户等级高抢到的概率和金额也较大
4、用户抢到的金额不能大于发放金额
5、追加的红包可以立即发放也可以延时发放
上面我们已经分析过红包雨的特点,要想实现一套高效的红包雨系统,缓存架构是关键。我们根据红包雨的特点设计 了如上图所示的红包雨缓存架构体系。
1、红包雨分批次导入到Redis缓存而不要每次操作数据库
2、很多用户抢红包的时候,为了避免1个红包被多人抢到,我们要采用Redis的队列存储红包 3、追加红包的时候,可以追加延时发放红包,也可以直接追加立即发放红包
4、用户抢购红包的时候,会先经过Nginx,通过Lua脚本查看缓存中是否存在红包,如果不存在红包,则直接终止抢红包
5、如果还存在红包,为了避免后台同时处理很多请求,这里采用队列术缓存用户请求,后端通过消费队列执行抢红包
用户抢红包的高并发场景下,如果让后端服务器直接处理所有抢红包操作,服务器很有可能会崩溃,就像高铁站如果 很多人蜂拥挤进站而不排队,很有可能导致整个高铁站秩序混乱,高铁站服务崩溃,程序也是如此,我们采用消息队列进行削峰。