分佈鎖

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 實現分佈鎖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章