在互联网分布式服务部署中,通常会遇到多个进程操作同一个资源的情况,例如秒杀等,此文章主要介绍使用Redis实现分布式锁。
Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。通常使用setnx(即set not exiest)来实现锁,以下通过循序渐进的方式引入最终实现。
方案一
1. C1通过setnx获取锁,处理业务,C1通过del释放锁
问题:如果处理业务期间C1崩溃,导致死锁
方案二
1. C1通过setnx获取锁,锁里面设置为时间戳,全局业务中有配置超时时间EXPIRE,处理业务,C1由于其他原因崩溃
2. C2,C3通过setnx获取锁失败
3. 使用get获取T1,T2,且CURTIME>T1(T2)+EXPIRE,超时(若未超时,则sleep,然后重新进入第2步)
4. C2,C3分别使用del删除锁
5. C2,C3分别使用setnx获取锁(若未获取到,则sleep,然后重新进入第2步)
问题:C2,C3串行执行情况下,C2获取的锁会被C3删除,从而导致竞态
方案三
1. C1通过setnx获取锁,锁里面设置为时间戳,全局业务中有配置超时时间EXPIRE,处理业务,C1由于其他原因崩溃
2. C2,C3通过setnx获取锁失败
3. 使用get获取T1,T2(为nil也进入判断),且CURTIME>T1(T2)+EXPIRE,超时(若未超时,则sleep,然后重新进入第2步)
4. C2,C3分别使用getset,获取到T11,T22(为nil也进入判断),此时若T11=T1则C2获取锁(T22=T2则C3获取锁,二者只会有1个成立),执行业务。(若未获取到的,则sleep,然后重新进入第2步)
网友评论