Hi, I’m Shendi
使用Redis实现分布式锁
需求场景
需要使用到分布式锁的场景非常多,例如抢单等并发场景,这里举一个例子。
有一个商品,限量出售100个,一个用户下单,数量就减少一个,当剩下最后一个时,用户A与用户B同时下单,同时查询剩余数量,得到为1,那么实际出售数量为101,而非100。这个时候就需要使用到分布式锁
Redis实现分布式锁
Redis是基于单线程的,这意味着所有来自客户端的命令都是顺序执行的,因此不必担心Redis内部的并发问题。
最常用的是使用 SETNX
(SET if Not Exists)来实现分布式锁,这个命令当key不存在时才设置,并返回1,存在则不设置,并返回0。
为了避免死锁,还会设置超时时间(Expire),即使程序挂掉,没有释放锁,也会在指定时间后自动销毁锁。
SETNX k v
EXPIRE k 10
但这种操作并不是原子性的,比如执行 EXPIRE
时出错,就会导致死锁。
在Redis2.6.12版本后,扩展了SET
命令,可以像下面这样实现分布式锁。
SET 键 值 NX PX 超时毫秒
使用示例如下
可以看到,当没有数据的时候,设置返回 OK,有数据,设置返回null,并且不会更改已有数据的超时时间
剩下的就是在代码中使用Redis了,不同语言使用方法不同,这里就不列出来了。
END