學AI,好工作 就找北大青鳥
關注小青 聽課做題,輕松學習
周一至周日
4000-9696-28

終于搞懂分布式鎖是什么了!

來源:北大青鳥總部 2023年05月29日 10:36

摘要: 在分布式環(huán)境中,對資源的上鎖非常重要,通過分布式鎖解決了數(shù)據(jù)的一致性問題,本文介紹了三種分布式鎖的方案,各位可以根據(jù)自己業(yè)務實際情況選擇合適的方案。

當下在互聯(lián)網(wǎng)技術架構中,最流行的莫過于分布式架構了。為什么大家紛紛都采用分布式架構呢?


1、高效低廉,將部署在高性能機的程序分散在多個小型機中部署;

2、擴展性強,可隨著業(yè)務的擴展而橫向擴展系統(tǒng)的性能;

3、可靠性強,當系統(tǒng)中一臺或幾臺出現(xiàn)故障時,仍然有其它機器在提供服務;

4、并發(fā)性強,各臺機器同時運作提供服務。


分布式,真香!


不過使用分布式架構也會存在一些問題,最嚴重的問題便是數(shù)據(jù)一致性問題。因為業(yè)務是部署在多臺機器上,由于時間空間的不一致,從而導致數(shù)據(jù)會不一樣,分布式的CAP理論已經告訴我們“分布式系統(tǒng)無法同時滿足一致性Consistency、可用性Availability、分區(qū)容錯性Partitiontolerance,最多滿足兩項”。對于數(shù)據(jù)不一致的問題,互聯(lián)網(wǎng)有幾種思考,比如BASE服務基本可用,犧牲暫時的數(shù)據(jù)不一致,只要數(shù)據(jù)最終一致即可;采用分布式事務進行解決;采用分布式鎖進行解決。而今天我們要介紹的便是分布式鎖的解決方案。

首先來看一個具體的case解釋為什么需要分布式鎖。在電商業(yè)務采用分布式架構后,程序部署在3個tomcat容器中(1個tomcat容器代表一個服務器,3個tomcat可理解在北京上海深圳都有部署電商服務),成員變量A代表商品數(shù)量。在北京的Alice,上海的Bob,深圳的Tom,都分別發(fā)起了購買或取消iPhone12的用戶請求,經過Nginx負載均衡將Alice的請求發(fā)給了北京服務器,Bob的請求發(fā)給了上海服務器,Tom的請求發(fā)給了深圳服務器,這時候每臺服務器都會對iPhone12這個商品數(shù)量進行更改,Alice的請求是將商品數(shù)量加到200,Bob的請求是將商品數(shù)量減少100,Tom的請求是將商品數(shù)量加1,如果對于商品數(shù)量的修改沒有任何限制,整體就會亂起來,可能Bob的先減少,Tom的在增加,數(shù)據(jù)就完全亂了,所以需要分布式鎖解決方案。



鎖的概念并不是在分布式中才存在,傳統(tǒng)互聯(lián)網(wǎng)的開發(fā)中也存在鎖。比如在多進程處理請求時,內存資源就會不足,這時候操作系統(tǒng)會使用信號量來解決資源的搶奪,如果信號量的值大于0,則將信號量數(shù)值減1,同時分配內存資源,如果信號量的值小于0,則進程處于等待狀態(tài),有其他進程操作執(zhí)行完畢后,信號量數(shù)值加1,喚醒等待的進程。


總結一下,實現(xiàn)鎖有三個要素

1、有存儲鎖的空間,在多進程中,內存就是存儲鎖的空間,通過對鎖的控制實現(xiàn)不同進程的訪問控制。2、能唯一標識,不同的空間用不同的鎖保護,那必須要唯一標識。
3、有狀態(tài),即存在、不存在。在分布式系統(tǒng)環(huán)境中,分布式鎖就是一個變量一個方法在同一時間只能被一個機器的一個線程執(zhí)行,對分布式鎖的實現(xiàn)也提出了更高的要求,即需要高性能高可用的獲取與釋放鎖,需要鎖超時機制,避免死鎖出現(xiàn)。


那么如何實現(xiàn)分布式鎖呢?業(yè)內有三種實現(xiàn)方式:

1、基于數(shù)據(jù)庫;

2、基于redis;

3、基于Zookeeper。


對于第一種實現(xiàn)方案,很簡單,我們知道在傳統(tǒng)數(shù)據(jù)庫中是有ACID事務原子性、一致性、持久性、可用性規(guī)則的,如果基于數(shù)據(jù)庫實現(xiàn)分布式鎖,只需要在數(shù)據(jù)庫中創(chuàng)建一個表,表中包含方法名,對方法名加上唯一索引,想要執(zhí)行該方法時,就使用這個方法名向表中插入數(shù)據(jù),插入時,其它數(shù)據(jù)都沒法插入,等于獲得鎖,成功插入后,刪除對應的數(shù)據(jù)釋放鎖。這種方案的好處就是簡單,但存在的問題是對數(shù)據(jù)庫要求高,因為數(shù)據(jù)庫的可用性、性能會直接影響分布式鎖的可用性,數(shù)據(jù)庫可能需要主從部署、讀寫分離。

對于第二種實現(xiàn)方案,只需要使用redis的命令setnx、expire、delete就可以了(請允許我再感嘆一下,redis真的太好用了,又簡單性能又好),setnxkeyvalue就會給某個變量賦予一個值,返回1,當業(yè)務請求來時,如返回key值為1,線程獲得鎖,如果key值為0,線程搶鎖失敗。

對于第三種實現(xiàn)方案,我們知道zookeeper是一個分布式協(xié)調服務,它內部是一個分層的文件系統(tǒng)目錄樹結構,同一個目錄下只能有一個唯一文件名,因此當實現(xiàn)分布式鎖時,只需要創(chuàng)建一個目錄,線程想要獲取鎖就在目錄下創(chuàng)建臨時順序節(jié)點,然后遍歷獲取是否存在比自己小的節(jié)點,如果存在則獲取鎖失敗,如果不存在則獲取鎖成功,缺點就是會頻繁的創(chuàng)建節(jié)點。

通過本文的介紹,認真閱讀的小伙伴又獲得了分布式架構使用的一個技巧。在分布式環(huán)境中,對資源的上鎖非常重要,通過分布式鎖解決了數(shù)據(jù)的一致性問題,小伙伴們可以根據(jù)自己業(yè)務實際情況選擇合適的分布式鎖方案噢~

標簽: redis
熱門班型時間
人工智能就業(yè)班 即將爆滿
AI應用線上班 即將爆滿
UI設計全能班 即將爆滿
數(shù)據(jù)分析綜合班 即將爆滿
軟件開發(fā)全能班 爆滿開班
網(wǎng)絡安全運營班 爆滿開班
報名優(yōu)惠
免費試聽
課程資料
官方微信
返回頂部
培訓課程 熱門話題 站內鏈接