Redis锁那些事儿,面试中怎么用它才能脱颖而出分享
- 问答
- 2025-12-28 06:18:57
- 4
Redis分布式锁,你可能已经背熟了SETNX命令,知道要用它来加锁,用DEL命令来解锁,但如果面试中你只说到这个程度,那可能只是达到了及格线,怎样才能让你的回答脱颖而出,让面试官觉得你不仅会用,还真正思考过背后的坑和最佳实践呢?关键就在于,你要主动去聊那些“坑”和“解决方案”。
我们从最基础的实现说起,来源一《Redis深度探险》里提到,最直观的想法就是用SETNX命令,SETNX是“SET if Not eXists”的缩写,意思是只有当这个key不存在时,才能设置成功,如果设置成功了,我就算拿到了锁;如果没成功,说明锁已经被别人拿走了,用完了之后,再用DEL命令把key删掉,锁就释放了,听起来很简单,对吧?但这里马上就有第一个大坑:如果业务代码执行到一半,服务器宕机了,那这个锁就永远无法释放了,其他进程也就永远拿不到锁,这就是死锁。
怎么解决这个问题呢?你就要提到第二个关键点:给锁设置一个过期时间,即使拿到锁的进程挂了,超过一段时间后,Redis也会自动删除这个key,从而释放锁,设置过期时间有两种方式:一种是先用SETNX,然后再用EXPIRE命令,但这里又有一个坑:如果执行完SETNX后,在执行EXPIRE之前服务器宕机了,过期时间还是没设置上,更推荐另一种方式:用一条原子命令同时完成SETNX和设置过期时间,在Redis 2.6.12版本之后,可以直接用SET命令加上NX和PX选项,SET lock_key unique_value NX PX 10000,这条命令的意思是,只有当lock_key不存在时(NX)才设置,并且设置一个10000毫秒的过期时间(PX),这是一条原子命令,不会被打断,完美解决了死锁和命令非原子性的问题。
好,现在我们有了一个带过期时间的锁,是不是就高枕无忧了呢?远远没有,接下来你要抛出一个更经典的问题:锁误删,想象一个场景:客户端A拿到了锁,设置的超时时间是10秒,但是A的业务逻辑执行了太久,比如花了15秒,这个时候锁因为超时已经自动释放了,紧接着,客户端B成功拿到了锁,客户端A执行完了,它去执行DEL命令删除锁,结果把客户端B刚创建的锁给删掉了!这就乱套了。
为了解决这个问题,你需要引入一个唯一标识符,来源二《分布式系统常用技术及案例分析》中强调了这一点,具体怎么做呢?在设置锁的时候,value不要简单地设为1,而是设为一个全局唯一的字符串,比如UUID或者请求ID,客户端在删除锁的时候,不能直接删,而是要先GET一下这个key的value,看看是不是自己当初设置的那个唯一值,如果是,才能删除;如果不是,说明这个锁已经不属于自己了,就不能删,这里又涉及到GET和DEL两条命令,不是原子操作,可能你GET完确认是自己的锁,正要DEL的时候,锁过期了,又被别人抢去,你还是可能误删。
最终的解决方案是使用Lua脚本,Redis支持执行Lua脚本,能保证脚本内的多条命令原子性执行,你可以写一个这样的Lua脚本:if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end,这条脚本的意思是,如果传入的key(KEYS[1])的值等于传入的第二个参数(ARGV[1],即你的唯一标识符),那么就删除它,否则返回0,这样,判断和删除的动作是原子性的,就彻底避免了锁误删的问题。
聊到这里,你已经把单机Redis分布式锁的核心要点和演进过程讲清楚了,但如果你想再进一步,可以稍微提一下更复杂的场景,比如RedLock算法,来源三马丁·克莱普曼的博客文章《How to do distributed locking》讨论了这个问题,当Redis本身是主从架构时,主节点挂了,从节点可能还没来得及同步锁信息就被提升为主节点,导致锁信息丢失,可能出现多个客户端同时拿到锁的情况,RedLock算法的核心思想是同时向多个(比如5个)独立的Redis实例申请锁,只有当超过半数的实例都成功拿到锁,才算真正获取成功,这样可以提高锁的可靠性,不过在面试中,你只需要点出单机Redis锁在集群下的潜在问题,并提及RedLock是解决思路之一,展现出你的知识广度即可,除非面试官深入追问,否则不必展开细节。
在面试中回答Redis锁的问题,不要只停留在SETNX和DEL,你要像一个讲故事的人,把从简单实现,到遇到死锁坑,引入过期时间;再遇到误删坑,引入唯一标识符和Lua脚本;最后提到集群环境下的挑战和RedLock思路,这个由浅入深的过程,清晰地展现了你解决问题的思维能力和对细节的把握,这绝对能让你在众多面试者中脱颖而出。

本文由钊智敏于2025-12-28发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/69869.html
