中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

基于Redis緩存怎么實現分布式鎖

發布時間:2021-12-27 16:53:30 來源:億速云 閱讀:190 作者:iii 欄目:大數據

本篇內容介紹了“基于Redis緩存怎么實現分布式鎖”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

什么是分布式鎖

首先我們先來簡單了解一下什么是分布式鎖。

在引入分布式鎖之前大家應該都知道經典的 CAP 理論提到任何一個系統都無法同時滿足一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance)三者的,同一時刻只能滿足兩個,在這種情況下分布式鎖就出現了,分布式鎖就是用來解決數據一致性問題的。

在以前單體應用的環境下,Java 的 API 提供了很多控制并發的接口,包括 synchronized 以及 JUC 下面的一些實現,但是在分布式環境下這些 API 就沒有用武之地了,因為應用是多實例部署的,很多實例甚至都不在同一臺主機上,根本無法使用 Java 中的 API,這個時候分布式鎖就誕生了。

所以簡單說什么是分布式鎖,分布式鎖就是在分布式環境下用來解決多實例對數據訪問一致性的一種技術方案。

使用場景

在實際環境中我們有很多場景會用到分布式鎖,例如全局計數器,只要涉及到多個實例進程對同一份數據進行修改等操作都會需要分布式鎖。在比如在下單,更新緩存,減少庫存等場景下也會用到分布式鎖的。

分布式鎖的特性

在看分布式鎖的實現之前,我們先了解下一個分布式鎖應該具備哪些特性:

  1. 在分布式環境下同一時刻只能被單個線程獲取;

  2. 可重入,意思是已經獲得鎖的線程在執行的過程中不需要再次獲得鎖;

  3. 異常或者超時自動刪除,避免死鎖;

  4. 高性能,分布式環境下必須要性能好;

實現方式

分布式鎖的實現方式流行的主要有三種,分別是基于緩存 Redis 的實現方式,基于 ZK 臨時順序節點的實現以及基于數據庫行鎖的實現。這里簡單提供下實現思路,不重復造輪子因為網上已經有很多開源的很好的解決方案了。

基于 Redis 緩存的實現

首先我們來看下基于 Redis 緩存實現的分布式鎖,Redis 支持 SETNX 命令,表示設置一個 key 的值當且進度 Key 不存在的時候才能設置成功。例如執行如下命令:set ziyou 18 NX PX 10000 表示將名叫 ziyou 的 key 的值設置為 18,當且僅當不存在名為 ziyou 的 key 的時候才能設置成功,并且過期時間設置為 10 秒鐘。

setnx 命令是 Redis 實現分布式鎖的核心,這個命令操作是原子操作的,千萬不能分兩步先用 set 再用 expire,這樣分開操作不是原子性的,無法實現效果。

然后 Redis 分布式鎖在網上有開源實現 [Redission](https://github.com/redisson/redisson),具體的實現可以參考。

百度也有一個開源的分布式 Redis 鎖叫 [dlock](https://github.com/baidu/dlock),我們采用就是這個,目前使用這么久還沒出現什么問題。使用方式類似下面:

基于Redis緩存怎么實現分布式鎖

優缺點

優點:

1. 實現簡單;

2. 理解邏輯簡單;

3. 性能好,畢竟是緩存。

缺點:

1. Redis 容易單點故障,集群部署;

2. key 的過期時間設置多少不明確,只能根據實際情況調整。


基于 ZK 的實現

前面提到 Redis 的核心的是 SETNX 命令,那么對于 ZK 來說,實現分布式鎖的核心是臨時順序節點。首先關于 ZK 的知識我們后面有機會再跟大家介紹,目前我們只要知道 ZK 的節點種類中有一種叫做臨時順序節點,兩個關鍵詞:臨時,順序。

臨時表示在客戶端創建某節點后,如果客戶端經過一段時間跟服務端之間失去了心跳,說明客戶端已經掉線了,那么這個節點就會被自動刪除(這一點跟 Redis key 的過期時間類似);順序的意思是在一個 node 下面生成的子節點是按順序的,每個子節點都有一個唯一編號,并且這個編號是按順序自增的。

臨時順序節點再加上 ZK 的監聽機制就可以實現分布式鎖了,Curator 是一個 ZK 的開源客戶端,也提供了分布式鎖的實現,這個我沒用實際用過,但是網上用的人也很多,大家可以自己去研究一下。

優缺點

優點:

1. ZK 本身就是集群部署,避免單機故障;

2. 順序節點所以不用考慮過期時間設置問題;

缺點:

1. 實現較為復雜;

2. 非緩存機制,大量頻繁創建刪除節點會影響 ZK 集群性能;

基于數據庫的實現

基于數據庫的分布式鎖個人覺得性能不是很好,在高并發的情況下對數據庫服務器的壓力過大,會影響業務,不建議使用。不過從學習的角度來看,我們還是有必要了解下具體的實現方式。基于數據庫的分布式鎖的實現大致有兩種方式,這里的數據庫我們以 MySQL 為例。兩種方案的實現都需要一個額外的表,并且要有一個唯一索引字段。

1. 阻塞式語句  select xxx for update 

2. 非阻塞試  insert into xxx ; delete from

解釋下:

第一種方案在實施的時候,需要關閉事務的自動提交,然后執行 SQL 去獲得鎖,如果獲得鎖成功,執行下面的業務邏輯,如果這里沒有獲取到鎖,則會阻塞,一直等待。業務執行結束后,手動提交事務。這里如果程序在執行提交事務失敗,異常或者服務宕機后,數據庫會自動釋放鎖,以免導致死鎖。但是這里有個問題就是如果在高并發的情況下,很多線程都沒有獲得到鎖,都在阻塞等待,這樣會導致數據庫的服務器壓力過大,會影響數據庫的服務。這個是要注意的,這也是我不建議的地方,容易出現瓶頸,畢竟沒有緩存高效。

第二種方案跟第一種類似,不一樣的地方是這里通過第一步向指定的表中插入一條唯一索引的數據,插入成功則表示獲得鎖,插入失敗則未獲得到鎖,成功獲得的鎖后就可以執行業務邏輯,在執行完業務邏輯后就可以刪除執行的記錄。如果插入失敗就需要重新觸發獲取鎖的動作。但是這種方案存在的問題是無法設置鎖的失效時間,需要其他手段來清理超時數據,而且為了支持可重入,需要將主機和服務的信息一起保存。

優缺點

優點

1. 容易理解和實現,但是細節要注意;

缺點:

1. 高并發的情況下性能不好,阻塞式的情況下很多鏈接不釋放會拖垮數據庫服務;

2. 需要定時清理超時數據,麻煩;

3. 數據庫的行鎖會因為 MySQL 的查詢優化而失效

“基于Redis緩存怎么實現分布式鎖”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

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

AI

灌云县| 余干县| 腾冲县| 鄂托克旗| 富锦市| 新巴尔虎左旗| 贵州省| 苍南县| 桓台县| 建瓯市| 时尚| 和田市| 龙海市| 页游| 玉林市| 梨树县| 枣阳市| 司法| 广水市| 长春市| 新安县| 西畴县| 玉屏| 宁夏| 镇平县| 商城县| 东方市| 台东县| 本溪| 紫阳县| 沐川县| 丹阳市| 武陟县| 湖南省| 舒城县| 垣曲县| 临洮县| 英德市| 云梦县| 廊坊市| 龙里县|