91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis常見分布鎖的原理是什么和怎么實現

發布時間:2022-08-25 14:58:56 來源:億速云 閱讀:174 作者:iii 欄目:關系型數據庫

今天小編給大家分享一下Redis常見分布鎖的原理是什么和怎么實現的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

常見的分布式鎖的實現如下圖:

Redis常見分布鎖的原理是什么和怎么實現

基于數據庫

悲觀鎖

悲觀鎖(Pessimistic Lock)顧名思義為很悲觀的鎖,每次在拿數據的時候都會上鎖。這樣別人想拿數據就被擋住,直到悲觀鎖被釋放,悲觀鎖中的共享資源每次只給一個線程使用,其它線程阻塞,用完后再把資源轉讓給其它線程,但是在效率方面,處理加鎖的機制會產生額外的開銷,且容易產生死鎖。

實現原理

悲觀并發控制實際上是"先取鎖再訪問"的保守策略,為數據處理的安全提供了保證.

Redis常見分布鎖的原理是什么和怎么實現

具體實現

例如通過悲觀鎖來實現庫存扣減的偽代碼如下:

// 對于庫存記錄進行行鎖

SELECT *FROM sys_goods s WHERE s.Id='1' FOR UPDATE;

//執行庫存扣減
update sys_stock s set s.stockQty=s.stockQty-#{number} where s.goodId=1 and s.stockQty>0;

//提交事務,自動釋放悲觀鎖。

樂觀鎖

簡介

樂觀鎖是基于數據版本號(version)的機制來實現的。數據庫表添加"version"字段, 讀取出數據時,將此版本號讀出,在更新過程中,會對版本號進行比較,如果是一致的,則會成功執行本次操作,且版本號加1,如果版本號不一致,則會更新失敗。

實現原理

相對悲觀鎖,樂觀鎖的實現不會使用到數據庫的鎖機制,樂觀鎖的原理使用的CAS的機制來實現的,CAS(Compare-and-Swap)即比較并替換.

Redis常見分布鎖的原理是什么和怎么實現

  • 1、比較:讀取到了一個值A,在將其更新為B之前,檢查原值是否仍為A(未被其他線程改動).

  • 2、設置:如果是未發送變化,則將A更新為B結束。如果發生變化,則什么都不做。

具體實現

例如樂觀鎖來實現庫存扣減的偽代碼如下:

// 查詢庫存記錄,獲取版本號
SELECT stockQty,version FROM sys_goods s WHERE s.Id='1'

//執行庫存扣減,防止出現超賣
update sys_stock s set 
  s.stockQty=s.stockQty-#{number},
  s.version=version+1
  where s.goodId=1 and s.stockQty>0 and version=#{version};

Redis實現分布式鎖

關于Redis分布式鎖的實現,已經在前期的文章中進行了講解,大家可以參考如下文章

Spring Boot 實現Redis分布式鎖原理

Spring Boot 集成Redisson實現分布式鎖詳細案例

Zooker實現分布式鎖

Zookper實現分布式鎖,主要是應用zookeeper節點的臨時和有序性來實現。

加鎖過程

當客戶端1請求時,Zookeeper客戶端會創建一個持久節點Locks節點,如果客戶端1想獲取鎖,會在locks節點下創建臨時節點/node_000000,如果查找Locks下面所有臨時有序子節點,當自己為最小的節點是則獲取鎖成功。

Redis常見分布鎖的原理是什么和怎么實現

當客戶端2嘗試獲取鎖時,也會查看locks下面的臨時節點,判斷自己的節點/node_000001是不是最小,如果不是最小則獲取鎖失敗,客戶端2會向它排序靠前的節點node_000000注冊watch事件,用來監聽node_000000是否存在,雖然搶鎖失敗,但是node_000001進入等待狀態。

Redis常見分布鎖的原理是什么和怎么實現

釋放鎖的過程

Zookeeper的客戶端業務完成或者客戶端發生故障,都會刪除臨時節點并且釋放鎖。如果是任務完成,客戶端1還會顯式調用刪除node_000000的指令。

Redis常見分布鎖的原理是什么和怎么實現

例如上述圖,客戶端1斷開,臨時節點node_000000已被刪除,而此時node_000001通過watcher監聽發現自己為為最小的臨時節點,所以獲取鎖成功。

異常場景分析

客戶端1創建臨時節點后,會與Zookeeper服務器維護一個Session,這個Session會依賴客戶端 定時心跳來維持連接。由于網路異常原因,Zookeeper長時間收不到客戶端1的心跳,就認為這個Session過期了,也會把這個臨時節點刪除,此時客戶端2創建臨時節點能夠獲取鎖成功。當客戶端網絡恢復正常后,它仍然認為持有鎖,此時就會造成鎖沖突。

具體實現

Zookeeper實現分布式鎖,可以采用Curator實現分布式鎖,關于SpringBoot如何集成Curator,大家可以參考如下文章:

Java Spring Boot 集成Zookeeper

Zookpeer實現分布式鎖實現庫存扣減

 @RequestMapping("/lockStock")
    public void lockStock()
    {
       zooKeeperUtil.lock("/Locks", 1000, TimeUnit.SECONDS, ()->{
           //業務邏輯
       });
    }

小結:

關于分布式鎖的實現的對比,詳情請查看下圖:

Redis常見分布鎖的原理是什么和怎么實現

以上就是“Redis常見分布鎖的原理是什么和怎么實現”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

涞源县| 彝良县| 香格里拉县| 博野县| 上思县| 财经| 赣州市| 神池县| 来安县| 红原县| 永昌县| 内乡县| 新巴尔虎右旗| 铜陵市| 和政县| 老河口市| 牡丹江市| 收藏| 黑龙江省| 手游| 怀来县| 吉首市| 营山县| 兴隆县| 庆安县| 景德镇市| 陆川县| 贞丰县| 墨脱县| 陵川县| 桦川县| 大渡口区| 内江市| 平乐县| 铅山县| 天台县| 凌海市| 志丹县| 荥经县| 惠来县| 阿拉善左旗|