源码来自https://github.com/study-only/go-locks
Redis分布式锁
Redis SET
命令
从Redis 2.6.12
版本开始,SET
命令的行为可以通过一系列参数来修改,详见Redis命令参考:
SET key value [EX seconds] [PX milliseconds] [NX|XX]
可选参数
EX seconds
:将键的过期时间设置为seconds
秒。 执行SET key value EX seconds
的效果等同于执行SETEX key seconds value
。PX milliseconds
:将键的过期时间设置为milliseconds
毫秒。 执行SET key value PX milliseconds
的效果等同于执行PSETEX key milliseconds value
。NX
: 只在键不存在时, 才对键进行设置操作。 执行SET key value NX
的效果等同于执行SETNX key value
。XX
: 只在键已经存在时, 才对键进行设置操作。
返回值
在Redis 2.6.12
版本以前,SET
命令总是返回 OK 。
从Redis 2.6.12
版本开始,SET
命令只在设置操作成功完成时才返回OK
; 如果命令使用了NX
或者XX
选项, 但是因为条件没达到而造成设置操作未执行, 那么命令将返回空批量回复(NULL Bulk Reply)
Redis分布式锁实现原理
从Redis命令看出,SET
命令为原子操作,我们可以用SET key value EX seconds NX
来实现分布式锁,下面为go语言实现:
import ( "errors" "time" "github.com/go-redis/redis" ) var redisClient *redis.Client type redisLock struct { name string expiry time.Duration } func (l *redisLock) TryLock() error { if ok, _ := redisClient.SetNX(l.name, 1, l.expiry).Result(); !ok { return errors.New("redis lock: already locked") } return nil } func (l *redisLock) Unlock() error { return redisClient.Del(l.name).Err() }