Redis為單進程單執行緒模式,採用佇列模式將並發存取變成串列訪問,且多客戶端對Redis的連線並不存在競爭關係。
程式碼實現的,主要是針對某一筆資料的流水號加鎖,防止多個執行緒寫入這個資料。 (具有互斥性) (建議學習:Redis影片教學)
現在最受歡迎的redis分散式鎖定就是Redisson了,來看看它的底層原理就了解redis是如何使用分散式鎖定的了
原理分析
分散式鎖定要解決的是分散式環境下,並行相同程式碼的加鎖功能;了解過redis分散式鎖的人肯定知道,一開始redis作為分散式鎖用的是setnx,再這基礎上設定個定時過期時間,但這種方式有什麼問題呢?
實際上看懂上圖的人也就明白了那有什麼問題,首先是原子性問題,setnx 過期時間這兩個操作必須是原子性的,所以這可以用lua腳本解決
再然後是釋放鎖定的時機該如何定?
不管我們定多少過期時間,都不能保證,在這段時間內鎖住的程式碼執行完成了,所以這個時間定多少都不好;
如果不定時間,當執行完成後釋放鎖,問題就是如果執行到一半機器宕機,那這把鎖就永遠放不掉了
那Redisson是如何解決上述問題的呢?
它對程式碼進行了精簡的封裝,我們的使用非常簡單,甚至我們不用主動設定過期時間
它設計了個watch dog看門狗,每隔10秒會檢查是否還持有鎖,若持有鎖,就給他更新過期時間30秒;透過這樣的設計,可以讓他在沒有釋放鎖之前一直持有鎖,哪怕宕機了,也能自動釋放鎖定
而無法取得鎖的客戶端則是不斷循環嘗試加鎖
透過記錄鎖定的客戶端id,可以把它設計成可重入鎖定
以上是為什麼redis可以做分散式鎖的詳細內容。更多資訊請關注PHP中文網其他相關文章!