Redis 分布式鎖

2022-01-10 17:00:54 字數 2352 閱讀 8880

一、分布式鎖實現

在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不存在。如給定的...