redis:
实际上是一个大map,数据模型为key,value,而且键值可以设置超时时间
redis实现分布式锁:
(1)方案1
利用命令 : setNx key value
存在key值则设置值,否则失败
释放锁 del key
获取A锁: setNx A "xxxxx"
func GetLock(A string) bool {
for {
if redis.SetNx(A, "uuid") {
return true
}
}
}
(2)上述方案存在问题,如果某个客户端获取锁后,所在的实例服务宕机了
解决方案:设置超时时间
官方demo:
set key value [EX seconds] [PX milliseconds] [NX|XX]
EX seconds:设置失效时长,单位秒
PX milliseconds:设置失效时长,单位毫秒
NX:key不存在时设置value,成功返回OK,失败返回(nil)
比如锁节点:/dir1/dir2
客户端获取uuid:(为啥+这个,者释放锁的时候del命名因为网络延迟等没有执行导致的超时)
获取锁命令:
set /dir1/dir2 uuid 超时时间 NX
释放锁命令:(需要用rua脚本,保证原子性,确保这个键锁是由当前客户端设置的)
下面是lua脚本,KEYS[1]是/dir1/dir2, ARGV[1]是uuid
if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end
(3)redLock 官方推出的最终方案,对redis的部署方式有要求