• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

openresty 中使用lua 的类库 lua-resty-lock,来实现异步非阻塞锁

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

LuaRestyLock:缓存失效风暴

看下下面的伪代码:

看上去没有什么问题,但是在进行压力测试的时候,会发现,每隔100秒,数据库的查询就会出现一次峰值。如果你的cache失效时间设置的过长,那么这个问题就会发现的概率比较小。

想象下,在cache失效的瞬间,如果并发请求10000条同时到了query_db(sql)回源到后端数据库中,如果数据库扛不住的话,那就会出现数据库死掉现象,导致不可用,这就是缓存失效瞬间引起的风暴。

解决方案:自然的想法是发现缓存失效后,加一把锁来控制数据库d的请求,这就要使用到lua_resty_lock类库了。

应对高并发系统,缓存是必不可少的利器,巧妙的使用缓存会使系统的性能有质的飞跃,下面就介绍一下本系统使用缓存的几种方式。

使用Redis缓存

首先看一下使用Redis缓存的简单数据流向图:

很典型的使用缓存的一种方式,这里先重点介绍一下在缓存命中与不命中时都做了哪些事。

当用户发起请求后,首先在Nginx这一层直接从Redis获取数据, 这个过程中Nginx使用lua-resty-redis操作Redis,该模块支持网络Socket和unix domain socket。如果命中缓存,则直接返回客户端。如果没有则回源请求数据,这里要记住另一个原则,不可『随意回源』(为了保护后端应用)。为了解决高并发下缓存失效后引发的雪崩效应,我们使用lua-resty-lock(异步非阻塞锁)来解决这个问题。

 

使用Nginx共享缓存,

Nginx共享缓存是worker共享的,也就是说它是一个全局的缓存,使用Nginx的lua_shared_dict配置指令定义。语法如下:

#指定一个100m的共享缓存 
lua_shared_dict cache 100m;

很多人一谈到锁就心有忌惮,认为一旦用上锁必然会影响性能,这种想法的不妥的。我们这里使用的lua-resty-lock是一个基于Nginx共享内存(ngx.shared.DICT)的非阻塞锁(基于Nginx的时间事件实现),说它是非阻塞的是因为它不会阻塞Nginx的worker进程,当某个key(请求)获取到该锁后,后续试图对该key再一次获取锁时都会『阻塞』在这里,但不会阻塞其它的key。当第一个获取锁的key将获取到的数据更新到缓存后,后续的key就不会再回源后端应用了,从而可以起到保护后端应用的作用。下面贴一段从官网弄过来的简化代码。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
【Lua篇】静态代码扫描分析(二)词法分析发布时间:2022-07-22
下一篇:
Nginx安装lua-nginx-module模块发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap