淺析Redis實現lock互斥訪問資源,淺析redislock互斥

來源:互聯網
上載者:User

淺析Redis實現lock互斥訪問資源,淺析redislock互斥
          Redis是當前很流行的一種開源鍵值資料庫。目前睿思的後台架構在資料庫層採用了Redis和MySQL組合的形式,其中Redis主要用來儲存狀態資訊(比如當前種子的peer)和讀寫頻繁的資料。Redis完全運行在記憶體之上,無lock設計,速度非常快!通過實測,在睿思伺服器上讀寫速度達到3萬次/s。
          在高並發的應用中,很多時候我們需要對某些資源進行競爭訪問,比如在很多人下載一個熱門資源,就可能存在很多請求去修改某個資源的peer資訊(就是儲存了當前保種人的ip地址和連接埠號碼),需要保證某個請求修改peer資訊的時候,不允許其他請求修改,否則就會出現資料覆蓋的問題。但是Redis沒有提供對資料的加鎖,所以需要我們通過Redis提供的命令自己實現:
思路一:通過get 和set 命令實現        這種方式很容易想到,就是當每次請求到來時通過get判斷這個鎖是否存在,如果不存在則set建立。這種方法有一個弊端,由於get和set是兩次Redis請求,二者之間有延時,在高並發的環境下,有可能在get檢測到鎖不存之後在set之前已經被其他線程set,這時當前線程再set,這樣鎖就失效了。所以這種方法只能應對並發量不是很高的情況。 
思路二:通過setnx 和 expire命令實現       在訪問需要互斥訪問的資源時,通過setnx命令去設定一個lock 鍵,setnx的作用是判斷鎖是否存在,如果不存在則建立,返回成功,如果存在則返回失敗,伺服器返回給用戶端,指示用戶端稍後重試。expire命令用於給該鎖設定一個到期時間,用於防止線程crash,導致鎖一直有效,從而導致死結。例如:設定鎖的有效期間為100秒,那麼即使線程奔潰,在100秒後鎖會自動失效。

setnx lock "lock"

如果成功則設定到期時間
expire lock 100

訪問互斥資源結束後,刪除鎖
del lock
 
思路三:通過watch和Redis的事務命令實現     這種方式的效果和思路二類似。在請求到時先watch改資源鎖,然後再通過在事務執行 建立鎖的過程,鎖的鍵值能唯一標識改請求(比如用時間+使用者標識)。如果當前還有其他線程請求該資源,當判斷該鎖存在時則返回錯誤重試(例如睿思BT tracker返回“伺服器過載,自動重試的”的提示就屬於此類情況)。如果有多個請求同時判斷改鎖不存在而建立鎖,這樣也會由於watch了這個鎖,導致之前watch的線程執行事務失敗,返回用戶端自動重試。這樣達最終達到了鎖的目的。



相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.