教你正确地使用Redis的SETNX实现锁机制


下面由redis教程栏目给大家介绍正确地使用redis的setnx实现锁机制,希望对需要的朋友有所帮助!

教你正确地使用Redis的SETNX实现锁机制

setNX,是set if not exists 的缩写,也就是只有不存在的时候才设置, 设置成功时返回 1 , 设置失败时返回 0 。可以利用它来实现锁的效果,但是很多人在使用的过程中都有一些问题没有考虑到。

例如某个查询数据库的接口因为请求量比较大所以加了缓存,并设定缓存过期后刷新。当并发量比较大并且缓存过期的瞬间,大量并发请求会直接查询数据库导致雪崩。如果使用锁机制来控制只有一个请求去更新缓存就能避免雪崩的问题。下面是很多人下意识想到的加锁方法

$rs = $redis->setNX($key, $value);
if ($rs) {
    //处理更新缓存逻辑
    // ......
    //删除锁
    $redis->del($key);
}

通过 setNX 获取锁,如果成功了则更新缓存然后删除锁。其实这里有一个严重的问题:如果更新缓存的时候因为某些原因意外退出了,那么这个锁就不会被删除而一直存在,以至于缓存再也得不到更新。为了解决这个问题有人可能会想到给锁设置一个过期时间,如下

Trae国内版 Trae国内版

国内首款AI原生IDE,专为中国开发者打造

Trae国内版 2045 查看详情 Trae国内版
$redis->multi();
$redis->setNX($key, $value);
$redis->expire($key, $ttl);
$redis->exec();

因为 setNX 不具备设置过期时间的功能,所以要借助 Expire 来设置,同时需要使用 Multi/Exec 来确保请求的原子性,以免 setNX 成功了 Expire 却失败了。这样还有问题:当多个请求到达时,虽然只有一个请求的 setNX 可以成功,但是任何一个请求的 Expire 却都可以成功,这就意味着即便获取不到锁也可以刷新过期时间,导致锁一直有效,还是解决不了上面的问题。显然 setNX 满足不了需求,Redis从 2.6.12 起,SET 涵盖了 SETEX 的功能, SET 本身又包含了设置过期时间的功能,所以使用 SET 就可以解决上面遇到的问题

$rs = $redis->set($key, $value, array('nx', 'ex' => $ttl));
if ($rs) {
    //处理更新缓存逻辑
    // ......
    //删除锁
    $redis->del($key);
}

到这一步其实还是有问题的,如果一个请求更新缓存的时间比锁的有效期还要长,导致在缓存更新过程中锁就失效了,此时另一个请求就会获取到锁,但前一个请求在缓存更新完毕的时候,直接删除锁的话就会出现误删其它请求创建的锁的情况。所以要避免这种问题,可以在创建锁的时候需要引入一个随机值并在删除锁的时候加以判断

$rs = $redis->set($key, $random, array('nx', 'ex' => $ttl));
if ($rs) {
     //处理更新缓存逻辑
    // ......
    //先判断随机数,是同一个则删除锁
    if ($redis->get($key) == $random) {
        $redis->del($key);
    }
}

以上就是教你正确地使用Redis的SETNX实现锁机制的详细内容,更多请关注其它相关文章!


# 正确地  # 教你  # Redis  # 本溪网站推广哪家好  # 靠谱的seo外包  # 营销型软件开发推广  # 企业网站建设网页  # seo实战模式  # 大沥镇网站建设  # seo排名软件seocnm  # 蒲江网站权重优化  # 亚马逊营销推广的内容  # 外推软件工具seo  # 量比  # 过程中  # 如何实现  # 网络带宽  # 只有一个  # 很多人  # 就会  # 国内 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 《波斯王子:失落的王冠》剑术大师打法攻略  word文档中的分隔符有哪些不同类型和用途_Word分隔符类型与用途方法  Sublime怎么快速复制文件路径_Sublime右键菜单增强技巧  电脑的“恢复环境(WinRE)”找不到怎么办_Windows系统恢复环境重建【高级修复】  Python自动化抓取GBGB赛狗比赛结果:日期范围与赛道筛选教程  优化Asyncio嵌套函数调度:使用生产者-消费者模式实现并发流处理  C#解析并修改XML后保存 如何确保格式与编码的正确性  《全民k歌》音乐怎么下载到本地2025  TikTok收藏夹无法删除视频如何解决 TikTok收藏管理优化方法  mysql中如何分析索引使用情况_mysql索引使用分析方法  小红书网页版在线直达 小红书网页版免费登录入口  《图怪兽》退出登录方法  C#中的Record类型有什么优势?C# 9新特性Record与Class的用法区别  电脑双系统如何安装和卸载 Windows和Linux双系统安装教程【详解】  mysql中如何配置字符集和排序规则_mysql字符集排序配置  iPhone12是否要更新ios16  《海豚家》注销账号方法  被称为海蜈蚣的海洋动物是  《一起考教师》账号注销方法  传统曲艺莲花落的表演形式是  《暗黑破坏神4》国服回归送狂欢礼包 价值6916元  J*a中导出MySQL表为SQL脚本的两种方法  Python测试中模块导入路径解析的最佳实践  漫蛙manwa2网页版书签同步链接_漫蛙manwa多设备登录入口  咸鱼怎么设置仅粉丝可见的动态_咸鱼动态粉丝可见设置方法  VS Code如何设置默认配置  苹果iPhone14ProMax如何新建AppleID_iPhone14ProMax新建AppleID具体流程  126邮箱申请入口官网_126邮箱注册免费登录2025  漫蛙漫画直连入口 _ manwa官方备用入口实时检测  Golang如何初始化module项目_Golang module init使用说明  Pydantic 中“schema”字段命名冲突的解决方案  cad加载的线型看不见怎么办_cad线型不可见问题解决方法  windows10怎么开启wsl_windows10安装linux子系统教程  动漫岛汉化官网网 动漫岛官方动漫汉化地址  苹果17 Pro如何启用分屏浏览_iPhone 17 Pro分屏浏览设置步骤  DeepSeek超全面指南:入门必看  抖音团长模式怎么做?团长模式是什么意思?  PHP页面重载时变量值不重置的实现方法  Dagster资产间数据传递与用户配置管理教程  Lar*el如何创建自定义的辅助函数(Helpers)_Lar*el全局函数定义与加载方法  oppo手机如何通过下拉通知栏截图_oppo手机通知栏快捷截图方法  抖音网页版地址直接进入_抖音网页版在线观看入口  优化 React onClick 事件处理:函数引用与箭头函数的对比  rabbitmq 持久化有什么缺点?  偃武诸葛亮阵容搭配推荐  J*aScript事件处理:优化键盘输入与表单提交的实践指南  j*a中赋值运算符是什么?  苹果手机如何清理系统缓存数据 iPhone非越狱清理垃圾文件的技巧【系统优化】  vivo手机视频通话美颜怎么设置_vivo视频通话美颜开启方法  AO3官方镜像链接 | 最新防走失网址永久收藏 

 2020-10-28

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.