WLock
● 項目名稱:WLock
● Github地址:
https://github.com/wuba/WLock.git
● 簡介:WLock是一套基于58已開源的一致性算法組件WPaxos實現(xiàn)的高可靠、高吞吐分布式鎖服務,可應用于分布式環(huán)境下協(xié)調多進程/線程對共享資源的訪問控制、多節(jié)點Master選主等業(yè)務場景。
核心特性
豐富的鎖類型:可重入鎖、公平鎖、優(yōu)先級鎖、讀寫鎖、進程鎖、線程鎖;
靈活的鎖操作:支持阻塞/非阻塞、同步/異步watch等方式獲取鎖,支持鎖續(xù)約,TTL等機制;
高可靠性:基于Paxos算法實現(xiàn)多副本數(shù)據(jù)同步,Master節(jié)點故障時主從自動切換,在無Master或者Master漂移過程仍可保證鎖狀態(tài)的持續(xù)一致性,不影響正常鎖操作;
高吞吐:多Paxos分組的Master均勻分布在所有集群節(jié)點,不同Paxos分組的鎖操作并行處理,相同Paxos分組鎖操作批量合并處理,大大提升了系統(tǒng)的吞吐量;
多租戶:提供秘鑰作為集群分配、鎖操作隔離、權限控制的租戶單位,支持單個秘鑰跨集群動態(tài)平滑遷移;
易用性:豐富的鎖接口封裝,開箱即用;
01 項目背景
在分布式部署的應用集群中,經(jīng)常會存在一些業(yè)務場景,為了保證某些業(yè)務邏輯的準確性,或者避免某些邏輯被重復執(zhí)行,需要限制多個應用進程或線程對共享數(shù)據(jù)資源進行互斥訪問,例如秒殺下單、商品搶購等場景,通常的解決方案是引入分布式鎖技術。
對于一些比較復雜的分布式場景,除了要求分布式鎖具有互斥性、避免死鎖、可重入等基本特性外,同時對分布式鎖服務的吞吐性能、數(shù)據(jù)一致性、可靠性等方面也有很強的要求,了解CAP理論的都知道,這是分布式系統(tǒng)設計的難點。當前已有的分布式鎖解決方案,也很難同時滿足這幾個特性,通常需要做出取舍,如基于Redis封裝實現(xiàn)的分布式鎖犧牲數(shù)據(jù)強一致性來保證吞吐量,或基于Zookeeper、Etcd封裝實現(xiàn)的分布式鎖犧牲一定的可用性保證數(shù)據(jù)強一致性。本項目希望提供一種分布式鎖方案,不僅滿足高吞吐的業(yè)務場景需求,還能夠保證服務具有比較高的可用性和可靠性。
02 設計實踐
功能架構如下:
目前開源的模塊主要包括負責鎖核心交互的客戶端、服務端,以及負責配置管理的注冊中心三部分。其中核心實現(xiàn)有以下幾個部分:
2.1 可靠存儲設計
WLock選擇高吞吐的鍵值存儲系統(tǒng)RocksDB來持久化鎖的狀態(tài)信息,基于WPaxos組件實現(xiàn)多副本數(shù)據(jù)同步以及主從自動切換能力;每個節(jié)點配置相同數(shù)量的Paxos分組,客戶端根據(jù)鎖名稱,將鎖哈希到某一個固定Paxos分組,默認將鎖請求發(fā)送到該Paxos分組對應的Master節(jié)點,鎖狀態(tài)更新時,由Master節(jié)點發(fā)起Propose請求同步給其它Slave節(jié)點,最終在執(zhí)行狀態(tài)機時寫入RocksDB,保證多副本數(shù)據(jù)的強一致性,如下圖所示:
我們知道Zookeeper、Etcd同樣也采用一致性協(xié)議實現(xiàn)多副本可靠存儲,但不同的是,它們只有單個Zab或Raft實例串行同步數(shù)據(jù),而WLock采用多Paxos分組機制,不同分組的Master在集群中均勻分布,集群節(jié)點對等部署,可并行同步數(shù)據(jù),大大提升了系統(tǒng)的吞吐能力;另外,得益于Paxos協(xié)議的靈活性,不對Master強依賴,當Master節(jié)點關閉或者出現(xiàn)異常時,未選出新的Master之前,可將鎖操作請求發(fā)送到指定的候選節(jié)點來處理,保證系統(tǒng)持續(xù)提供服務,具有更高的可用性。
2.2 鎖操作實現(xiàn)
WLock封裝提供了豐富的鎖類型如可重入鎖、公平鎖、優(yōu)先級鎖、讀寫鎖等,下面以可重入鎖為例,介紹下加鎖/釋放鎖實現(xiàn)。
阻塞/非阻塞獲取鎖
WLock提供有阻塞與非阻塞方式獲取鎖,區(qū)別在于是否等待服務端加鎖成功。非阻塞方式根據(jù)服務端鎖當時的狀態(tài),直接返回客戶端加鎖成功或失敗;而阻塞方式在鎖已被其它owner搶占的情況下,會在服務端內存注冊一個WatchEvent事件等待獲取鎖,當鎖被釋放時,服務端立即從Watch等待隊列中選擇一個優(yōu)先級最高的WatchEvent直接執(zhí)行加鎖,并通知喚醒監(jiān)聽的客戶端。
相對于其它分布式鎖通過客戶端定時輪詢實現(xiàn)的阻塞機制,WLock的阻塞機制在鎖競爭度比較高時,獲取鎖的延遲低、實時性更強,還能夠更好支持優(yōu)先級鎖,但也存在一個缺陷,WatchEvent長期存儲于服務端緩存隊列,若客戶端所在機器宕機或者出現(xiàn)一些網(wǎng)絡異常,服務端不能及時感知到客戶端異常變化時,掛起在服務端的WatchEvent變?yōu)闊o效狀態(tài)且不會被立即剔除,這時喚醒該WatchEvent加鎖成功后,不能成功通知到客戶端,鎖過期前又不能被其它客戶端搶占。為此,WLock引入兩種機制來優(yōu)化這個問題,
1)WatchEvent添加心跳;顧C制?蛻舳嗣扛20s定時向服務端發(fā)起WatchEvent心跳,服務端接收到后,發(fā)現(xiàn)WatchEvent已存在,便延長WatchEvent的有效時間,服務端定時檢測內存中WatchEvent是否有效,做過期剔除處理。
2)通過監(jiān)聽WatchEvent獲取到鎖時,客戶端首先進行續(xù)約Touch。服務端在選擇WatchEvent執(zhí)行加鎖時,會先把鎖的過期時間調整為Math.min(鎖真實過期時間,10s),客戶端收到加鎖成功通知后需要立即發(fā)起續(xù)約Touch,服務端收到續(xù)約請求后再延長鎖的過期時間為客戶端接口設置的真實過期時間。這樣,若通知的客戶端已不活躍,最長阻塞10s鎖不能被其它客戶端搶占。
該WatchEvent處理機制,同樣應用于異步Watch方式的加鎖處理。
可重入實現(xiàn)
WLock可重入機制是由客戶端通過鎖上下文中的AcquireCount原子變量計數(shù)控制,第一次獲取鎖時請求服務端加鎖,成功后進行本地計數(shù),其它情況下,將加鎖請求轉為續(xù)約鎖請求發(fā)送到服務端;釋放鎖過程,只有AcquireCount小于等于0時,才向服務端釋放鎖,否則只是本地計數(shù)減一處理。這樣設計考慮的是,若在服務端計數(shù)控制,在某些異常情況下,當返回客戶端的加鎖請求超時,實際服務端執(zhí)行加鎖計數(shù)成功時,可能會導致客戶端與服務端重入鎖計數(shù)不一致而產(chǎn)生死鎖。
TTL機制
為了避免死鎖,服務端要求每個鎖都設有過期時間,過期時間需要根據(jù)客戶端對共享資源正常訪問時間合理設置。如果設置太短,有可能在客戶端完成對共享資源訪問之前,鎖就發(fā)生過期,從而破壞鎖的安全性;如果設置太長,一旦某個持有鎖的客戶端釋放鎖失敗,就會導致一段時間內其它客戶端都無法獲到取到鎖。
WLock服務端限制鎖的過期時間最多為5分鐘,但是對客戶端設置的鎖過期時間則不做限制,對于過期時間超過5分鐘的加鎖請求,通過自動定時續(xù)約來延長鎖的過期時間,客戶端發(fā)送到服務端的加鎖和續(xù)約鎖請求中,攜帶的鎖過期時間最大也只能為5分鐘。自動續(xù)約周期默認為Math.min(鎖過期時間,5分鐘)的1/3(最小為1秒),這樣在鎖過期前,允許客戶端至少有兩次容錯機會。
WLock計算過期時間戳的方式是[加鎖成功的起始時間/續(xù)約鎖成功的起始時間+鎖過期時間],鎖過期檢測嚴格依賴機器時鐘,為了避免集群服務節(jié)點間的時鐘差異,導致不同節(jié)點計算鎖過期觸發(fā)時機不一致,WLock限制服務端只有Master節(jié)點主動檢測鎖的過期狀態(tài),檢測到鎖過期時,由Master發(fā)起Propose請求同步Slave節(jié)點對過期鎖進行刪除處理,并將ExpireEvent通知到客戶端,降低了時鐘不一致對鎖服務的影響。由于鎖過期檢測Task僅存儲在Master內存,當Master發(fā)生漂移時,新的Master需要從RocksDB中重新加載分組下所有Lockkey信息,生成鎖過期檢測Task分發(fā)到根據(jù)過期時間排序的優(yōu)先級隊列,并恢復檢測任務,這個過程通常在幾秒內完成,這期間可能會導致服務端檢測鎖過期存在延遲。為了不受服務端或網(wǎng)絡異常影響,WLock客戶端同時也開啟有鎖的過期檢測任務,鎖過期時間比服務端延遲了加鎖或續(xù)約請求Response網(wǎng)絡返回時間,客戶端對于過期回調的執(zhí)行做了冪等判斷,避免并發(fā)重復執(zhí)行。
大神 Martin Kleppmann在文章《How to do distributed locking》中對分布式鎖原理進行論證時,指出Redlock可能存在的安全問題:當客戶端獲取到鎖后發(fā)生GC pause或者服務端出現(xiàn)時鐘回退,有可能在鎖持有者釋放鎖之前,鎖就發(fā)生過期,此時如果另外一個客戶端搶占到鎖,鎖的互斥性會被破壞。WLock同樣是引入了鎖版本號(fencing token)來解決這個問題,但是需要用戶自己在訪問共享資源時,攜帶并比較當前資源更新操作的鎖最大版本號(類似于樂觀鎖機制),再結合事務機制保證數(shù)據(jù)操作的一致性。
續(xù)約機制
WLock支持主動和自動兩種續(xù)約機制,主動續(xù)約機制可通過客戶端調用續(xù)約接口觸發(fā),自動續(xù)約機制可在加鎖時通過參數(shù)配置啟動。由于續(xù)約線程與鎖持有線程通常為兩個線程,自動續(xù)約機制存在一定的安全風險,業(yè)務在加鎖處理邏輯的外層finally邏輯中一定要釋放鎖(遠程釋放鎖前,會先停止自動續(xù)約任務),否則鎖持有線程異常退出時,鎖自動續(xù)約還會一直執(zhí)行,導致鎖永遠不過期,出現(xiàn)死鎖。
事件補償
WLock通過[Host, Pid,ThreadID]來定義一個鎖Owner,ThreadID為-1時鎖為進程粒度,否則為線程粒度。鎖owner不會隨著客戶端與服務端連接狀態(tài)的更新而變化,但鎖狀態(tài)發(fā)生變更時,服務端會向鎖owner或者鎖監(jiān)聽者主動推送一些事件如WatchEvent、ExpireEvent,為此,服務端需要維護鎖owner或鎖監(jiān)聽者與客戶端連接的對應關系。
當WLock服務端Master發(fā)生漂移或者網(wǎng)絡連接異常重連時,客戶端連接綁定關系會同時發(fā)生變更,此時就需要客戶端主動進行事件補償,補償類型包括兩種:
1)WatchEvent事件補償,重新向服務端注冊監(jiān)聽事件,服務端更新WatchEvent與客戶端連接綁定關系。
2)AcquireEvent事件補償,客戶端對已持有的鎖進行續(xù)約,服務端收到請求后不更新鎖的過期時間,只更新鎖owner與客戶端連接的對應關系。
2.3. 高并發(fā)優(yōu)化
前面提到,WLock通過引入多Paxos分組,多節(jié)點互為主備對等部署并行同步數(shù)據(jù)的集群架構,已經(jīng)一定程度上提升了系統(tǒng)的吞吐能力。此外,Wlock還充分利用了WPaxos組件批量Propose的功能,對單分組的鎖操作實現(xiàn)做了以下優(yōu)化,進一步提升了系統(tǒng)的并發(fā)處理能力:
1)單個Paxos分組采用多線程并行處理鎖請求,相同Lockkey的鎖請求哈希到同一個線程串行處理;
2)對單個Paxos分組下不同線程阻塞的鎖請求進行合并,批量發(fā)起Propose同步數(shù)據(jù),降低了網(wǎng)絡傳輸與多任務調用切換成本。
03 為什么選擇WLock
在分布式領域中,分布式鎖已經(jīng)是一種比較成熟的技術,現(xiàn)有的實現(xiàn)方案已有很多,為什么還開發(fā)WLock,優(yōu)勢又有哪些?接下來我們從功能、服務特性、性能三個維度,介紹下常見的幾種分布式鎖的差異點。
功能
服務特性
性能
測試運行環(huán)境
機器配置:CPU:20 x Intel(R) Xeon(R) Silver 4114 CPU @ 2.20GHz
內存:192 GB
硬盤:SSD
網(wǎng)卡:萬兆網(wǎng)卡
服務端集群機器個數(shù):3臺
測試結果
1. 單客戶端qps:
2. 相同并發(fā)下,請求響應延遲(單位ms)
說明:以上對比測試的中數(shù)據(jù),Redis、ZK、Etcd相關非官方數(shù)據(jù),均由我們在相同環(huán)境下實際壓測得到。其中,對于QPS的統(tǒng)計,客戶端請求一次加鎖再請求一次釋放鎖合并為一次計數(shù),更詳細的壓測數(shù)據(jù)及壓測條件可查看開源對比文檔。
通過以上幾個維度的測試分析,WLock的優(yōu)勢在于可靠性與系統(tǒng)吞吐量比較高,處理延遲略低于Redis,但明顯高于Zookeeper與Etcd,為此,對于分布式鎖選型有以下建議:
對可靠性要求不高,響應延遲比較敏感的場景,鎖并發(fā)低于3W時可使用Redis,高于3W建議用WLock;
對可靠性要求比較高,同時鎖并發(fā)高于500的場景,可使用WLock;
04 未來規(guī)劃
1. 提供GO、PHP、Node等多語言SDK
2. 開源WEB管控中心、監(jiān)控模塊
3. 支持分布式信號量機制
參考資料
WPaxos源碼地址:https://github.com/wuba/WPaxos
開源|WPaxos:一致性算法Paxos的生產(chǎn)級高性能Java實現(xiàn):https://mp.weixin.qq.com/s/bydpMwTWAamS3u8Ko57iYg
How to do distributed locking:
https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html
作者簡介
劉丹,58同城后端架構師,58分布式消息隊列、分布式鎖、分布式鏈路追蹤等系統(tǒng)負責人
文章內容僅供閱讀,不構成投資建議,請謹慎對待。投資者據(jù)此操作,風險自擔。
近日,德國柏林國際電子消費品展覽會(IFA2024)隆重舉辦。憑借在核心技術、產(chǎn)品設計及應用方面的創(chuàng)新變革,全球領先的智能終端企業(yè)TCL實業(yè)成功斬獲兩項“IFA全球產(chǎn)品設計創(chuàng)新大獎”金獎,有力證明了其在全球市場的強大影響力。
近日,中國家電及消費電子博覽會(AWE 2024)隆重開幕。全球領先的智能終端企業(yè)TCL實業(yè)攜多款創(chuàng)新技術和新品亮相,以敢為精神勇闖技術無人區(qū),斬獲四項AWE 2024艾普蘭大獎。
“以前都要去窗口辦,一套流程下來都要半個月了,現(xiàn)在方便多了!”打開“重慶公積金”微信小程序,按照提示流程提交相關材料,僅幾秒鐘,重慶市民曾某的賬戶就打進了21600元。
由世界人工智能大會組委會、上海市經(jīng)信委、徐匯區(qū)政府、臨港新片區(qū)管委會共同指導,由上海市人工智能行業(yè)協(xié)會聯(lián)合上海人工智能實驗室、上海臨港經(jīng)濟發(fā)展(集團)有限公司、開放原子開源基金會主辦的“2024全球開發(fā)者先鋒大會”,將于2024年3月23日至24日舉辦。