redis分布式锁
加锁
1 判断锁是否被占用,没有则获取锁(hset/hincrby)并设置过期时间(expire)
2 如果锁被占用,则判断是否是当前线程占用,如果是获取锁(hset/hincrby)并设置过期时间(expire)
3 否则获取锁失败
if redis.call('exists',KEYS[1])==0 or redis.call('hexists',KEYS[1],ARGV[1]) ==1 then redis.call('hincrby',KEYS[1],ARGV[1],1) redis.call('expire',KEYS[1],ARGV[2]) return 1 else return 0 end
释放锁
1 判断自己的锁是否存在(hexists),不存在返回nil
2 如果存在则减1(hincrby-1),判断减1后是否为0 ,为0则del,并返回1
3 如果不为0,则返回0
if redis.call('hexists',KEYS[1],ARGV[1])==0 then return nil elseif redis.call('hincrby',KEYS[1],ARGV[1],-1)==0 then return redis.call('del',KEYS[1]) else return 0 end
续期
判断自己的锁是否存在hexists,如果存在则重置过期时间
if redis.call('hexists',KEYS[1],ARGV[1])==1 then return redis.call('expire',KEYS[1],ARGV[2]) else return 0 end
redis 测试脚本
加锁 eval "if redis.call('exists',KEYS[1])==0 or redis.call('hexists',KEYS[1],ARGV[1]) ==1 then redis.call('hincrby',KEYS[1],ARGV[1],1) redis.call('expire',KEYS[1],ARGV[2]) return 1 else return 0 end" 1 lock 1234567890 30 释放锁 eval "if redis.call('hexists',KEYS[1],ARGV[1])==0 then return nil elseif redis.call('hincrby',KEYS[1],ARGV[1],-1)==0 then return redis.call('del',KEYS[1]) else return 0 end" 1 lock 1234567891 续期 eval "if redis.call('hexists',KEYS[1],ARGV[1])==1 then return redis.call('expire',KEYS[1],ARGV[2]) else return 0 end" 1 lock 1234567890 30