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

溫馨提示×

溫馨提示×

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

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

分布式鎖的原理與實現是什么

發布時間:2021-10-13 09:53:12 來源:億速云 閱讀:126 作者:iii 欄目:編程語言

這篇文章主要講解了“分布式鎖的原理與實現是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“分布式鎖的原理與實現是什么”吧!

為什么會出現分布式鎖?

如下圖所示,一個應用被部署到多個機器上做負載均衡。為了保證一個方法或屬性在高并發情況下的同一時間只能被同一個線程執行,我們該如何解決這個問題呢?
分布式鎖的原理與實現是什么
在傳統單體應用單機部署的情況下,可以使用并發處理相關的功能(如Java并發處理相關的API:ReentrantLcok或synchronized)進行互斥控制來解決。但是,隨著業務的發展,系統架構也會逐步優化升級,原本單體單機部署的系統被演化成分布式集群系統,由于分布式系統多線程、多進程并且分布在多個不同機器上,這將使原單機部署情況下的并發控制鎖策略無法滿足,并不能提供分布式鎖的能力。為了解決這個問題就需要一種跨機器的互斥機制來控制共享資源的訪問,這就是分布式鎖解決的難題!

分布式鎖應用場景有哪些?

針對分布式鎖的目的來反向推導其應用場景,主要包括兩類:

1、處理效率提升:應用分布式鎖,可以減少重復任務的執行,避免資源處理效率的浪費;

2、數據準確性保障:使用分布式鎖可以放在數據資源的并發訪問,避免數據不一致情況,甚至數據損失等。

分布式鎖的實現前提

分布式的CAP理論:

任何一個分布式系統都無法同時滿足一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance),最多只能同時滿足兩項。

通常情況下,大家都會犧牲強一致性來換取系統的高可用性,這樣我們很多的場景,其實是只需為了保證數據的“最終一致性”。
需要注意的是,這個最終時間需要是用戶可以接受的范圍內的。

另外,要實現分布式鎖,需要具備一些條件,主要包括以下幾項:

1、在分布式系統環境下,一個方法在同一時間只能被一個機器的一個線程執行;
2、獲取鎖與釋放鎖的高可用及高性能;
3、具備非阻塞鎖特性,獲取不到鎖將直接返回獲取鎖失敗;
4、具備鎖失效機制,防止死鎖。

上述條件,主要突出鎖本身的提效和保障準確性的應用特性,同時避免其本身對資源訪問造成影響;

實現方式有哪些呢?

關于分布式鎖的實現,可以分別控制在不同的環節。

分布式鎖的原理與實現是什么

常見的主要分為以下這幾種:

1、開源組件鎖控制:ZooKeeper

ZooKeeper 是一個分布式協調服務的開源框架。主要用來解決分布式集群中應用系統的一致性的問題,例如怎樣避免同時操作同一數據造成臟讀的問題。ZooKeeper 本質上是一個分布式的小文件存儲系統。提供基于類似于文件系統的目錄樹方式的數據存儲,并且可以對樹種的節點進行有效管理。
分布式鎖的原理與實現是什么
那如何使用ZooKeeper實現分布式鎖?

1)客戶端連接zookeeper,并在/tmp下創建臨時的且有序的子節點,第一個客戶端對應的子節點為lock-0000,第二個為lock-0001,以此類推;

2)客戶端獲取/lock下的子節點列表,判斷自己創建的子節點是否為當前子節點列表中序號最小的子節點,如果是則認為獲得鎖,否則監聽剛好在自己之前一位的子節點刪除消息,獲得子節點變更通知后重復此步驟直至獲得鎖;

例如/tmp下的子節點列表為:lock-0000、lock-0001、lock-0002,序號為1的客戶端監聽序號為0的子節點刪除消息,序號為2的監聽序號為1的子節點刪除消息。(業務代碼執行完即刪除子節點)

3)執行業務代碼流程,刪除當前客戶端對應的子節點,鎖釋放。

ZooKeeper分布式鎖方式,性能相對Redis方式較差,主要原因是寫操作(獲取鎖釋放鎖)都需要在Leader上執行,然后同步到follower。

2、任務處理鎖控制:Redis

Redis 是完全開源免費的,遵守BSD協議,是一個高性能的key-value數據庫。
主要的優勢包括:

  • 性能極高 – Redis能讀的速度是11w+次/s,寫的速度是8w+次/s

  • 豐富的數據類型 – Redis主要支持 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型

  • 原子性 – Redis的所有操作都是原子性的,同時Redis還支持對幾個操作合并后的原子性執行

  • 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性。

Redis實現簡單分布式鎖過程:

(1)獲取鎖:使用setnx加鎖,并使用expire命令為鎖添加一個超時時間,超過該時間則自動釋放鎖,鎖的value值為一個隨機生成的UUID,通過此在釋放鎖的時候進行判斷。

(2)獲取鎖:設置一個獲取的超時時間,若超過這個時間則放棄獲取鎖。

(3)釋放鎖:通過UUID判斷是不是該鎖,若是該鎖,則執行delete進行鎖釋放。

分布式鎖的原理與實現是什么
利用Redis實現分布式鎖,實現可能存在的缺點:

在執行delete進行釋放鎖的時候,假如操作刪除鎖動作失敗,那此 Key-Value 過期時間則不好控制,可能會一直存在,可能對后續數據驗證造成影響。

3、數據寫入鎖控制:MySQL

數據庫層面是最終數據寫入的時候,對數據做寫入控制處理,算是分布式鎖的最終末端環節。主要包括以下三種方式,下面分別介紹一下。

實現方式一:唯一索引

UNIQUE KEY `uidx_name` (`name`) USING BTREE;

上述case中,我們對 name 字段做了索引的唯一性約束,當存在多個新增數據請求同時提交到數據庫的話,數據庫自身則會利用唯一索引,來保證數據的唯一性。

實現方式二:排他鎖

執行以下SQL:

SELECT status FROM users WHERE id = 3 FOR UPDATE;

假如,在另一個事務中再次執行:

SELECT status FROM users WHERE id = 3 FOR UPDATE;

則第二個事務會一直等待上一個事務的提交,此時第二個查詢處于阻塞的狀態。

排它鎖的應用:

在進行事務操作時,通過 “FOR UPDATE” 語句,MySQL會對查詢結果集中每行數據都添加排他鎖,其他線程對該記錄的更新與刪除操作都會阻塞。排他鎖包含行鎖、表鎖。

實現方式三:樂觀鎖

實現邏輯:樂觀鎖每次在執行數據修改操作時,都會帶上一個數據版本號,一旦版本號和數據的版本號一致就可以執行修改操作并對版本號執行+1 操作,否則就執行失敗。因為每次操作的版本號都會隨之增加,所以不會出現 ABA 問題。

除了 version 以外,還可以使用時間戳,因為時間戳天然具有順序遞增性。

比較麻煩的一點:就是在操作業務前,需要先查詢出當前的 version 版本。

數據庫分布式鎖實現可能存在的缺點:

  • DB操作性能較差,并且有鎖表的風險;

  • 非阻塞操作失敗后,需要輪詢,占用cpu資源;

  • 長時間不commit或者長時間輪詢,可能會占用較多連接資源

感謝各位的閱讀,以上就是“分布式鎖的原理與實現是什么”的內容了,經過本文的學習后,相信大家對分布式鎖的原理與實現是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

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

AI

随州市| 民权县| 上林县| 淮阳县| 茌平县| 彩票| 平塘县| 灵川县| 双辽市| 台北县| 开封市| 屯留县| 汝州市| 文昌市| 八宿县| 邯郸县| 安新县| 开化县| 云梦县| 渑池县| 丽水市| 宣化县| 嘉义市| 革吉县| 重庆市| 琼结县| 松滋市| 伊川县| 融水| 东山县| 闸北区| 青龙| 五莲县| 溧水县| 四子王旗| 南开区| 广安市| 丹东市| 新干县| 大兴区| 平定县|