分布式锁的实现与探索
源寶導讀:大型的信息化系統對數據準確性的要求很高,所以經常會使用事務、鎖、隊列等技術,保障高并發下的數據一致性問題。本文將討論在分布式部署模式下,如何利用鎖機制保證業務數據準確的技術探索與實踐。
一、背景
???分布式場景下的數據一致性問一直是一個非常重要的話題,在很多場景中,我們需要使用各種技術方案來保證數據的一致性,比如分布式事務、分布式存儲、分布式鎖等。有些業務場景中,我們需要保證一個方法在同一時間內只能被一個線程執行,來解決一些譬如商品超賣,我們ERP中的一房多賣、財務票據號跳票重復等問題。在單機環境中,各種語言其實提供了較多并發處理相關的特性,比如.Net中的lock、Monitor、Mutex等,但是這些特性在分布式場景中就有問題了。針對分布式鎖的實現,目前比較常用的有這樣幾種:數據庫實現、緩存實現(redis,memcached)、Zookeeper實現、以及etcd等。
二、利用數據庫實現分布式鎖
基于數據庫唯一約束
? ? 應該是分布式鎖最簡單的方式之一,創建一張鎖表,通過數據庫的唯一約束,當我們需要鎖住某個場景時,插入一條數據,插入成功則獲鎖成功可以執行后續操作,操作完成后刪除記錄來釋放鎖資源。我們老系統即提供了此種類型的鎖來處理各類鎖場景。
數據庫約束實現的鎖問題:
強依賴數據庫,單點無高可用,數據庫宕掉則業務不可用。
并發支撐不夠,單點的數據庫成為瓶頸。
非阻塞的,沒有獲得鎖的無法排隊直接失敗。
非重入的,同一線程無法再次獲取已經得到的鎖。
沒有失效時間,如果解鎖失敗則業務受阻。
利用數據庫特性實現
? ? 利用SQL Server提供的應用鎖來實現鎖定,使用sp_getapplock加鎖,sp_releaseappLock釋放鎖,隨事務提交或回滾:
? ? 相對于數據庫唯一約束實現來說,更加簡便,好控制,不占用數據庫空間,而且支持阻塞特性實現排隊等待,且業務失敗自動釋放(回滾),目前ERP使用此方案來實現鎖控制,開箱即用,不依賴其他服務。
三、利用緩存實現分布式鎖
? ? 相比于數據庫實現,基于緩存的鎖實現性能更好,可以支撐更高的并發,同時緩存的集群部署可以保證高可用。
MemCached
? ? 利用Memcached的原子命令add操作,只有add成功才表示獲取到鎖。由于MemCached采用LUR置換策略,可能導致并未過期的鎖信息被刪除,且無持久化。
Redis
? ? 同樣利用其原子操作,來處理鎖定場景,官方也提供了Relock的dotnet實現。
? ? RedLock算法提出通過N/2 + 1(半數以上實例)獲取到鎖并且獲取時間小于鎖過期時間則認為獲取到鎖,來解決Master-Slave模式下主從同步失敗導致的鎖安全問題,但實際上還是可能由于某一節點未落盤宕機或則時鐘不同步導致多客戶端獲鎖成功的問題,本身AP,想完全CP就比較別扭了,這也是RedLock被質疑的地方。
? ? 同時通過retry機制實現阻塞(間隔一段時間,重試獲鎖過程),不過重試間隔不好把握,這一點java的實現Redisson提供了另外的方式,在申請鎖失敗后,阻塞線程,通過訂閱解鎖消息來釋放阻塞并重試獲鎖過程,同時也可以利用watch dog來實現鎖延時。
四、利用Zookeeper實現分布式鎖
? ??可以通過其有序臨時節點+監聽節點刪除來實現分布式鎖,通過僅監聽上一個節點的刪除事件避免羊群效應,具體流程如下圖:
可基于Zookeeper的客戶端,按照上述流程實現:
也可以使用ZookeeperNet.Recipes提供的鎖:
相比于redis,性能弱于redis,但健壯性更好(更能保障數據一致)。
五、利用etcd實現分布式鎖
? ? etcd可能沒有ZK那么被大眾熟知,但說它為K8s提供狀態配置存儲就明白了。
? ? 和ZK功能相似,使用Raft保證數據一致性,相較于zookeeper,ecd使用GO編寫更加輕便,其效率也更高,在etcd v3版本中已提供了lock的封裝。
官方推薦的dotnet的客戶端如下:
dotnet-etcd使用google的gRPC框架封裝了客戶端各操作,包括V3提供的鎖:
六、總結
? ? 沒有完美的技術,只有合適的選擇,就如CAP原則最多只能同時滿足兩種特性一樣,復雜性、高可用、高性能等方面很難同時滿足,選擇適合當前業務要求的即可。怕的是沒有意識到并發情況會產生數據不一致的問題,導致的超賣現象以及跳號重復等問題的產生,之前處理過比較多的反饋,希望通過此篇文章讓大家意識到分布式環境下可能出現的數據不一致的問題,并選擇合適的方案來解決。
------ END ------
作者簡介
王同學:?架構師,目前負責售樓產品的相關架構規劃和設計工作。
也許您還想看
.NET Core MVC擴展實踐
如何使用有序GUID提升數據庫讀寫性能
.Net最小工作線程對應用程序性能的影響
ERP緩存實踐經驗分享
總結
以上是生活随笔為你收集整理的分布式锁的实现与探索的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【实战 Ids4】║ 给授权服务器加个锁
- 下一篇: 【原创】StackOverflow 20