Redis锁其实没那么牢靠,安全问题让它根本锁不住资源,别太信了
- 问答
- 2026-01-17 17:54:41
- 4
(来源:某技术社区资深开发者分享的实际案例)

Redis锁,很多人觉得用个setnx命令,或者用那个叫Redisson的库里的现成方法,就能高枕无忧地锁住资源,防止多个程序同时操作把数据搞乱,但说实话,这东西的可靠性被过分高估了,真到了复杂点的生产环境,它可能比你想象的要脆弱得多,根本锁不住你想保护的资源,原因就出在几个看似不起眼但实际上要命的安全问题上。

第一个大问题,也是老生常谈的,就是锁的过期时间到底设多久才合适?这简直是个无解的难题。(来源:Redis官方文档关于分布式锁的说明)你用Redis锁,肯定得给它设置一个过期时间吧,不然万一你的程序挂了,锁没释放,那其他所有程序就都永远卡住,这叫死锁,比不锁还糟糕,但问题来了,这个时间你怎么定?设短了,比如5秒,万一你的业务逻辑执行起来比较耗时,用了6秒,那完蛋了,在你还没执行完的时候,锁已经因为到期被Redis自动删除了,这时候另一个程序趁机拿到了锁,也开始操作同一个资源,得,两个程序同时改一份数据,锁形同虚设,数据大概率就乱套了,那你设长点,设30秒总够了吧?但如果你的程序真的在5秒内就处理完了,剩下的25秒这把锁就成了摆设,白白占着茅坑不拉屎,降低了系统的吞吐能力,更关键的是,你很难精确预估每一个业务操作的执行时间,网络抖动一下、数据库慢查询一下,都可能让你的预估失效,单是靠设置一个固定的过期时间,这个基础就不牢靠。
第二个问题更隐蔽,叫“误删别人的锁”。(来源:一篇广为流传的分布式锁缺陷分析文章)假设程序A成功加锁,锁的键是“update_order_123”,值呢,我们一般会设成一个唯一的标识,比如UUID,然后A开始执行业务,这时候,如果A因为垃圾回收或者系统负载高,导致它“卡顿”了(也就是我们说的STW),这个卡顿时间超过了锁的过期时间,Redis一看锁过期了,就把它删了,程序B此时趁虚而入,成功地给“update_order_123”加上了自己的锁(带着B自己的UUID值),紧接着,A从卡顿中苏醒过来,它不知道自己已经超时了,还傻乎乎地继续执行后续代码,最后在执行完毕时,它做了一个释放锁的操作,可怕的事情发生了:A用自己的UUID作为凭证去删除锁,但此时锁的UUID是B的,按理说A不应该能删除B的锁,对吧?如果释放锁的逻辑写得不够严谨,比如就是简单地去删除“update_order_123”这个键,那么A就会把B刚刚创建的新锁给删掉!这下可好,程序B还以为自己安全地持有着锁呢,实际上锁已经没了,程序C可能马上就能加锁成功,又来操作资源,这就造成了不止两个程序,甚至可能多个程序交叉运行,数据不乱套才怪,虽然Redisson这类库用一些机制试图解决这个问题,比如用 Lua 脚本保证原子性,但并不能完全根除因进程长时间停顿带来的风险。
第三个问题,在于Redis本身。(来源:一次线上故障的事后总结报告)你想想,你的锁存在哪?存在Redis里,如果你的Redis是单机部署,那么这台机器万一宕机了,你的锁就全没了,即使Redis有持久化机制,从硬盘恢复数据也需要时间,这段时间里锁服务是完全不可用的,那你说我用Redis哨兵或者集群模式搞高可用总行了吧?事情也没那么简单,在Redis的主从复制模式下,数据从主节点同步到从节点是异步的。(来源:Redis作者Antirez本人撰写的关于Redlock算法的讨论)假设你在主节点上成功加锁了,但还没来得及同步到从节点,主节点就宕机了,哨兵机制会选举一个从节点升级为新的主节点,可惜这个新主节点上并没有你刚才加的那把锁,这时,另一个客户端来向新主节点申请同样的锁,居然也能成功!同一个锁又被发出了第二把,又出现了两个客户端同时持有锁的情况,虽然Redis作者提出了一个叫Redlock的算法来试图在分布式环境下实现更安全的锁,但这个算法本身也引发了巨大的争议,比如Martin Kleppmann就写过长篇大论指出其潜在的问题,需要依赖非常多理想化的假设,比如所有节点都拥有近乎同步的时钟、网络延迟有严格上限等,这些在真实的、不可靠的网络世界里很难百分百保证。
综合来看,Redis锁更像是一个在简单场景下、对数据一致性要求不是那么苛刻的场景下,一个轻量级的、有一定效果的互斥工具,它很快,很方便,但如果你的业务场景要求的是强一致性,要求锁必须百分之百可靠,比如涉及到金钱交易、库存扣减等,那么盲目相信Redis锁是非常危险的,它底层这些关于过期时间难以设定、进程停顿导致锁失效、以及Redis集群架构本身固有的数据一致性问题,都让它这个“锁”显得千疮百孔,根本锁不住你珍视的资源,真到了关键地方,可能还是需要用数据库的悲观锁、或者更重量级但设计更严谨的分布式协调服务(比如ZooKeeper、etcd)来实现真正的锁机制,别太迷信Redis锁了,了解它的缺陷,才能更好地使用它,或者在有风险的时候果断放弃它。

本文由符海莹于2026-01-17发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/82549.html
