分布锁

redission 分布锁

redission 分布锁使用了map 这种数据结构,key为锁的名称,map的key客户端,value为重入的个数

代码进行分析,大致代码都写到RedissionLock这个类里。

加锁:

//判断该锁是否存在,如果该锁不存在
if (redis.call('exists', KEYS[1]) == 0) 
	向map类型中添加数据, key为客户端id ,value 为 1 ,表示当前锁重入的个数为1
	then redis.call('hset', KEYS[1], ARGV[2], 1); 
	设置过期时间 ,默认为30秒
	redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; 
	
//如果存在该锁,并且该锁的持有者和当前客户端id相同
if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) 
	//将重入的个数加 1 
	then redis.call('hincrby', KEYS[1], ARGV[2], 1); 
	redis.call('pexpire', KEYS[1], ARGV[1]); 
	返回0
	return nil; end; 

//上述都不符合的话,就返回该key的过期时间
return redis.call('pttl', KEYS[1]);


key1 是要加锁的key

argv1 锁的key默认生存时间

argv2 加锁的客户端id,为生成的 UUID + thread_id ,UUID会在redission客户端对象创建的时候生成

释放锁:


0代表释放失败,1代表释放成功

//如果锁不存在
if (redis.call('exists', KEYS[1]) == 0) 
//发送释放锁的消息,返回1 
	then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;
//如果持有该锁的客户端id 不是当前id ,释放锁失败	
if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; 

//如果锁的持有者和当前客户端id一致,将可重如个数-1 
local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); 
//如果当前可重入锁的个数大于0,说明锁不可以被释放
if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0;
 
//如果当前可重入锁的个数为0,说明锁可以被释放
else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; 

//否则返回null 
return nil;

详细信息可以查看 分布式锁

 

zookepper 实现分布锁:

详见 zookeeper 实现分布锁

你可能感兴趣的:(分布式)