分散式系統中如何實現臨界資源的互斥訪問?

語言: CN / TW / HK

摘要: 一次僅允許一個程序使用的資源稱為臨界資源。

本文分享自華為雲社群《 分散式系統中如何實現臨界資源的互斥訪問 》,作者:華為雲PaaS服務小智。

網路時代,購物、社交等之前只能在線下進行的活動,如今都可以在網路上完成。為了促進消費,電商網、網路店鋪經常推出商品限定數量內的“秒殺”,“搶購”活動,類似的臨界資源訪問還有我們生活中常見的微信多人搶紅包。這種臨界資源,多人訪問的情況,如何保證避免一個資源被多人(一人以上)互斥訪問呢?

臨界資源

多道程式系統中存在許多程序,它們共享各種資源,然而有很多資源一次只能供一個程序使用。一次僅允許一個程序使用的資源稱為臨界資源。

上面我們提到的在搶購中對商品提交訂單,微信中開啟多人紅包都屬於這種臨界資源的訪問,一次只允許一個程序使用。

臨界資源互斥訪問

分散式互斥是隨著分散式系統的出現而出現的,並隨著分散式系統理論發展而發展。在分散式系統中,很多程序能夠在微觀上並行執行。但由於共享資源的有限性,以及全域性資料要求的一致性,一些臨界資源的訪問需要以互斥的方式實現同步。

Java原生鎖

在傳統單機部署的情況下,可以使用Java併發處理相關的API(如ReentrantLock或synchronized)進行互斥控制。這種Java提供的原生鎖機制可以保證在同一個Java虛擬機器程序內的多個執行緒同步執行,避免出現無序現象。

但在網際網路場景,特別是搶購活動中,隨著整個系統的併發訪問飆升,需要多臺機器併發執行,以應對使用者井噴式訪問,假設此時多個使用者的請求同時到來,但落在了不同的機器上,雖然這兩個請求是可以同時執行,但是因為兩個機器執行在兩個不同的Java虛擬機器裡面,他們加的鎖只對屬於自己Java虛擬機器裡面的執行緒有效,對於其他Java虛擬機器的執行緒是無效的。因此,Java提供的原生鎖機制在多機部署場景下失效了,這是因為兩臺機器加的鎖不是同一個鎖(兩個鎖在不同的Java虛擬機器裡面),這樣便會出現庫存超賣的現象。

分散式鎖

基於存在的現狀,我們只要保證多臺機器加的鎖是同一個鎖,用加鎖的方式對某種資源進行順序訪問控制。這就需要分散式鎖登場了。

分散式鎖是一種解決分散式臨界資源併發讀寫的一種技術,對分散式應用加鎖,能夠避免出現庫存超賣及無序訪問等現象。

分散式鎖的思路是:在整個系統提供一個全域性、唯一的獲取鎖的“東西”,然後每個系統在需要加鎖時,都去問這個“東西”拿到一把鎖,這樣不同的系統拿到的就可以認為是同一把鎖。

當前分散式加鎖主要有三種方式:(磁碟)資料庫、快取資料庫、Zookeeper。

用 Redis 實現分散式鎖

使用Redis型別的快取例項實現分散式加鎖,有幾大優勢:

• 加鎖操作簡單,使用SET、GET、DEL等幾條簡單命令即可實現鎖的獲取和釋放。

• 效能優越,快取資料的讀寫優於磁碟資料庫與Zookeeper。

如下圖中所示,使用redis的set方法即可實現對臨界資源加鎖,點選此 獲取全量 程式碼 

使用redis的del方法即可實現鎖的釋放。

相對於傳統redis,如今各大雲廠商也都推出了 redis 雲服務,以即開即用、安全可靠、彈性擴容、便捷管理等特點受到軟體開發企業和開發者的歡迎。

參考資料

李美安. 普適分散式互斥演算法及應用[D]. 電子科技大學, 2006.

點選關注,第一時間瞭解華為雲新鮮技術~