首頁 > 資料庫 > Redis > 主體

如何使用redis來實現分散式鎖

(*-*)浩
發布: 2019-11-29 10:25:53
原創
4495 人瀏覽過

如何使用redis來實現分散式鎖

分散式鎖定其實可以理解為:控制分散式系統有序的去對共享資源進行操作,透過互斥來保持一致性。

舉個不太恰當的例子:假設共享的資源就是一個房子,裡面有各種書,分散式系統就是要進屋看書的人,分散式鎖就是保證這個房子只有一個門並且一次只有一個人可以進,而且門只有一把鑰匙。 (建議學習:Redis影片教學

#使用redis實作分散式鎖定                     

編號# -lock-time 實作加鎖

使用redis指令EVAL 實作解鎖

#加鎖:

Jedis jedis = new Jedis("127.0.0.1", 6379);
 
 private static final String SUCCESS = "OK";
 
 /**
 
  * 加锁操作
 
  * @param key 锁标识
 
  * @param value 客户端标识
 
  * @param timeOut 过期时间
 
  */
 
 public Boolean lock(String key,String value,Long timeOut){
 
     String var1 = jedis.set(key,value,"NX","EX",timeOut);
 
     if(LOCK_SUCCESS.equals(var1)){
 
         return true;
 
     }
 
     return false;
 
 }
登入後複製

解讀:

加上鎖定操作:jedis.set(key,value,"NX","EX",timeOut)【保證加鎖的原子操作】

key就是redis的key值作為鎖的標識,value在這裡作為客戶端的標識,只有key-value都比配才有刪除鎖的權利【保證安全性】

透過timeOut設定過期時間保證不會出現死鎖【避免死鎖】

NX,EX什麼意思?

NX:只有這個key不存才的時候才會進行操作,if not exists;

EX:設定key的過期時間為秒,具體時間由第5個參數決定

解鎖

Jedis jedis = new Jedis("127.0.0.1", 6379);
 
 private static final Long UNLOCK_SUCCESS = 1L;
 
 /**
 
  * 解锁操作
 
  * @param key 锁标识
 
  * @param value 客户端标识
 
  * @return
 
  */
 
 public static Boolean unLock(String key,String value){
 
     String luaScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else  return 0 end";
 
     Object var2 = jedis.eval(luaScript,Collections.singletonList(key), Collections.singletonList(value));
 
     if (UNLOCK_SUCCESS == var2) {
 
         return true;
 
     }
    return false;
 }
登入後複製

解讀:

luaScript 這個字串是個lua腳本,代表的意思是如果根據key拿到的value跟傳入的value相同就執行del,否則就回傳0【保證安全性】

jedis.eval(String,list,list);這個指令就是去執行lua腳本,KEYS的集合就是第二個參數,ARGV的集合就是第三參數【保證解鎖的原子操作】

上述就實現了怎麼使用redis去正確的實現分散式鎖,但是有個小缺陷就是鎖過期時間要設定為多少合適,這個其實還是需要去依照業務場景來考慮的。

更多Redis相關技術文章,請造訪

Redis入門教學欄位學習!

以上是如何使用redis來實現分散式鎖的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板