一、分布式鎖實現
在unix 系統程式設計中,遇到多個程序或者執行緒共享一塊資源的時候,通常會使用系統自身提供的鎖,譬如乙個程序裡的多執行緒,會用互斥鎖;多個程序之間,會用訊號量等。這個場景中所謂的共享資源僅僅限於本地,倘若共享資源存在於網路上,本地的「鎖」就不起作用了。互斥訪問某個網路上的資源,需要有乙個存在於網路上的鎖伺服器,負責鎖的申請與**。 redis 可以充當鎖伺服器的角色。首先, redis 是單程序單執行緒的工作模式,所有前來申請鎖資源的請求都被排隊處理,能保證鎖資源的同步訪問。
可以借助 redis 管理鎖資源,來實現網路資源的互斥。
我們可以在 redis 伺服器設定乙個鍵值對,用以表示一把互斥鎖,當申請鎖的時候,要求申請方設定( set)這個鍵值對,當釋放鎖的時候,要求釋放方刪除( del )這個鍵值對。
二、死鎖的問題
首先是客戶端崩潰導致的死鎖。按照上面的方法,當某個客戶端申請鎖後因崩潰等原因無法釋放鎖,那麼其他客戶端無法申請鎖,會導致死鎖。
一般,申請鎖是為了讓多個訪問方對某塊資料作互斤訪問(修改),而我們應該將訪問的時間控制在足夠短,如果持有鎖的時間過長,系統整體的效能肯定是下降的。可以給定乙個足夠長的超時時間,當訪問方超時後尚未釋放鎖,可以自動把鎖釋放。
redis 提供了ttl 功能,鍵值對在超時後會自動被剔除,在 redis的資料集中有乙個雜湊表專門用作鍵值對的超時。所以,我們有下面的 lua **:
//設定鎖的lua指令碼private static final string setnx_expire_script = "if redis.call('setnx', keys[1], keys[2]) == 1 then\n"+ "return redis.call('expire', keys[1], keys[3]);\n" + "end\n" + "return nil;";
...redis.eval(setnx_expire_script, 3, key, value, seconds + "");
//引數 1 指令碼 2 指令碼引數個數 3 ... 引數
附:jedis 工具類
package com.redis.disconf.util;import redis.clients.jedis.jedis
;import redis.clients.jedis.jedispool;
/** * created by windwant on 2017/6/8.
*/public class jedisutil }}
/*** 獲取jedis例項
* @return
*/public static jedis getjedis()
return null;}
/*** 登出pool
*/public static void destory()}}
}/**
* 釋放
* @param jedis
*/public static void returnresource(jedis jedis)
}//設定鎖的lua指令碼
private static final string setnx_expire_script = "if redis.call('setnx', keys[1], keys[2]) == 1 then\n"+ "return redis.call('expire', keys[1], keys[3]);\n" + "end\n" + "return nil;";
/** * 設定鎖的lua指令碼
* private static final string setnx_expire_script = "if redis.call('setnx', keys[1], keys[2]) == 1 then\n"* "return redis.call('expire', keys[1], keys[3]);\n" + "end\n" + "return nil;";
* * @param key
* @return
*/public static boolean trylock(string key, string value,integer seconds) finally
return lock;}
/*** 釋放鎖
* @param key
* @return
*/public static boolean unlock(string key) finally
return unlock;}
}
示例專案:
redis分布式鎖
redis分布式鎖 直接上 我寫了四個redis分布式鎖的方法,大家可以提個意見 第一種方法 redis分布式鎖 param timeout public void lock long timeout thread.sleep 100 catch exception e override publi...
Redis分布式鎖
分布式鎖一般有三種實現方式 1.資料庫樂觀鎖 2.基於redis的分布式鎖 3.基於zookeeper的分布式鎖.首先,為了確保分布式鎖可用,我們至少要確保鎖的實現同時滿足以下四個條件 互斥性。在任意時刻,只有乙個客戶端能持有鎖。不會發生死鎖。即使有乙個客戶端在持有鎖的期間崩潰而沒有主動解鎖,也能保...
redis分布式鎖
使用redis的setnx命令實現分布式鎖 redis為單程序單執行緒模式,採用佇列模式將併發訪問變成序列訪問,且多個客戶端對redis的連線並不存在競爭關係。redis的setnx命令可以方便的實現分布式鎖。setnx key value 將key的值設為value,當且僅當key不存在。如給定的...