20200829 redis 分布式鎖

2021-10-24 00:16:01 字數 1999 閱讀 5151

那麼分布式鎖,如何保證不同機器不同執行緒的分布式鎖同步

同乙個時刻,只能有乙個客戶端持有鎖

如果持有鎖的客戶端崩潰沒有主動釋放鎖,也要保證鎖可以正常釋放及其他客戶端可以正常加鎖。

只要有redis節點還存活著,就可以進行正常的加鎖

保證互斥和防止死鎖,首先想到的使用redis的setnx命令保證互斥,為了防止死鎖,鎖需要設定乙個超時時間。

public static void wronglock(jedis jedis, string key, string uniqueid, int expiretime) 

}

在多執行緒併發環境下,任何非原子性的操作,都可能導致問題。這段**中,如果設定過期時間時,redis例項崩潰,就無法設定過期時間。如果客戶端沒有正確的釋放鎖,那麼該鎖(永遠不會過期),就永遠不會被釋放。

比較容易想到的就是設定值和超時時間為原子原子操作就可以解決問題。那使用setnx命令,將value設定為過期時間不就ok了嗎?

value設定為過期時間,就要求各個客戶端嚴格的時鐘同步,這就需要使用到同步時鐘。即使有同步時鐘,分布式的伺服器一般來說時間肯定是存在少許誤差的。

鎖過期時,使用 jedis.getset雖然可以保證只有乙個執行緒設定成功,但是不能保證加鎖和解鎖為同乙個客戶端,因為沒有標誌鎖是哪個客戶端設定的嘛。

直接刪除key

public static void wrongreleaselock(jedis jedis, string key)
不是被自己加的鎖,直接被釋放

判斷自己是不是鎖的持有者,如果是,則只有持有者才可以釋放鎖。

public static void wrongreleaselock(jedis jedis, string key, string uniqueid) 

}

看起來很完美啊,但是如果你判斷的時候鎖是自己持有的,這時鎖超時自動釋放了。然後又被其他客戶端重新上鎖,然後當前執行緒執行到jedis.del(key),這樣這個執行緒不就刪除了其他執行緒上的鎖嘛,好像有點亂套了哦!

基本上避免了以上幾種錯誤方式之外,就是正確的方式了。要滿足以下幾個條件:

命令必須保證互斥

設定的key必須要有過期時間,防止崩潰時鎖無法釋放

value使用唯一id標誌每個客戶端,保證只有鎖的持有者才可以釋放鎖

加鎖直接使用set命令同時設定唯一id和過期時間;其中解鎖稍微複雜些,加鎖之後可以返回唯一id,標誌此鎖是該客戶端鎖擁有;釋放鎖時要先判斷擁有者是否是自己,然後刪除,這個需要redis的lua指令碼保證兩個命令的原子性執行。

下面是具體的加鎖和釋放鎖的**:

@slf4j

public class redisdistributedlock

// 不斷嘗試加鎖

public string lock()

try catch (interruptedexception e)

}} catch (exception ex)

return null;

}public boolean release(string value)

// 判斷key存在並且刪除key必須是乙個原子操作

// 且誰擁有鎖,誰釋放

string script = "if redis.call('get', keys[1]) == ar**[1] then return redis.call('del', keys[1]) else return 0 end";

object result = new object();

try ", value);

return true;

}} catch (exception e) finally

}log.info("release lock failed, value:{}, result:{}", value, result);

return false;

}}

Redis(十一) Redis分布式鎖

為什麼需要使用分布式鎖 因為synchronize和lock是乙個jvm中線程級別的鎖。如何應用部署在多台伺服器上 多個jvm 那synchronize和lock就不起作用了。所以需要分布式鎖來保證符合操作的原子性。1 基於資料庫 2 zookeeper分布式鎖 高一致性,效能較差 3 基於redi...

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的分布式鎖.首先,為了確保分布式鎖可用,我們至少要確保鎖的實現同時滿足以下四個條件 互斥性。在任意時刻,只有乙個客戶端能持有鎖。不會發生死鎖。即使有乙個客戶端在持有鎖的期間崩潰而沒有主動解鎖,也能保...