redis 分布式锁实现
Posted gm-201705
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis 分布式锁实现相关的知识,希望对你有一定的参考价值。
我们实现的分布式锁,使用redis提供的SET NX功能,由于redis server的单线程模型,保证了天然并发安全。
https://stackoverflow.com/questions/11658272/is-redis-list-or-set-pop-method-thread-safe
client A通过 SET key value1 NX 获得锁,client B 不断block retry set key value2 NX直到获得锁。(retry时间一般以十毫秒为单位,权衡了cpu占用与获取锁的及时性)
1)需要为key设置EX,防止client拿到锁后程序崩溃,锁一直得不到释放。这个值的设定要衡量实际拿到锁的业务处理时间。
2)value要使用随机生成的值,保证不重复,推荐可以使用UUID version1。目的是为不使client A处理超时,锁过期自动释放,client A误删了client B获取到的锁。
这里更好的处理方式是lock duration超过后,主动停掉正在进行的任务,因为使用锁本身即不希望代码并发执行。
3)使用的codis,防止了一台redis server的单点问题,但依然存在网络的单点。目前实现存在的缺点,但由于资源问题暂时无法解决。
1. random value
func randomValue() string {
return uuid.NewV1().String()
}
2. 获取锁
v := randomValue()
ok, err := l.client.SetNX(l.k, v, l.expiration).Result()
if err == redis.Nil {
err = nil // set failed, key already exist.
}
if err != nil {
return err // set failed, some error
} else if ok {
l.v = v
return nil
}
3. 释放锁
var rlsFunc = redis.NewScript(`
if redis.call("get", KEYS[1]) == ARGV[1] then
return
redis.call("del", KEYS[1])
else
return 0
end`)
以上是关于redis 分布式锁实现的主要内容,如果未能解决你的问题,请参考以下文章