分布式入門之1:Lease機制


 
引子:
分布式系統中,如何確認一個節點是否工作正常?
 
如果有3副本A、B、C,並通過中心結點M來管理。其中A為主副本。
未接觸過分布式的直觀的處理方法是在每個副本與中心節點M中維護一個心跳,期望通過心跳是否存在而判斷對方是否依舊存活。
心跳方法其實根本無法解決分布式下的這個問題。考慮如下場景:
M在某時刻未能預期收到主節點A的心跳,M認為A已經異常,於是從B、C中選取一個B作為主節點。但實際上A並未異常,而是由於網絡瞬時阻塞、或是M本身出現異常使A這消息暫時未收到。這時,系統中出現A、B兩個都是主節點的情況,稱“雙主”問題,從節點C可能同時從這兩個主節點同步數據,這會引發很嚴重的數據錯誤。
因此,需要更合理的機制來判斷節點是否正常工作。
 
 
主要思路有兩種:一是設計能容忍雙主的分布式協議,二是用lease機制。
一涉及去中心化,不討論。
 
lease的原理:
lease的思想非常簡單,既然中心節點需要獲取目標節點是否異常的情況,同時又要考慮網絡出問題等異常,那就干脆考慮各種異常情況在內,只單方面給對方一個期限,在這個期限內,我認為你是正常的,不正常也認為正常。超出這個期限,我就認為你異常了。由於網絡延遲等原因,這個期限不能使用相對時間,而必須使用絕對時間。比如,1點之間,節點A就是主節點。這樣就能避免雙主問題。節點A為如果收到這個lease,即得到了中心節點的授權,1點前絕對只有自己是主。心跳依舊照發,只是每次中心節點都只根據lease是否有效來判斷節點狀況,不會出問題。
 
lease是一種頒發的帶期限的承諾,有兩方面的意義: 頒發者在承諾期限內一定遵守承諾,被頒發者在承諾期限內可放心行使承諾的內容;期限過了以后,被頒發者一定不可再行使承諾。
 
lease與活鎖
lease的頒發往往是被動的,比如A節點需要中心節點的某個承諾,比如讀並緩存,則會向中心節點請求lease,中心節點回復最新可緩存的數據與一個lease,在此lease期限內,中心節點保證目標節點緩存內容與中心節點一致。
按lease方案,如果中心節點需要修改對應數據,必須等全部lease失效。問題是等lease失效的過程中,可能有新的請求元數據的請求到達,這時中心節點又會繼續頒發新的lease,使得lease一直不結束,形成“活鎖”,即修改請求等待lease失效,而又源源不斷頒發新lease而一直無法完成。
解決活鎖的辦法:當有修改請求在等待着lease失效時,如果后續有讀請求,則 只返回請求數據而不頒發新lease,或者是只頒發目前最長的lease。
解決活鎖后,修改請求仍然需要等待全部lease結束,寫請求可能阻塞太久。可以在寫請求到達時,中心節點 主動給各節點發取消lease的消息。如果全部正確返回,則寫可立即進行。如果有異常,那就正常等待lease結束。
 
lease的容錯:
由於僅依賴於絕對時間,因此lease機制天生即可容忍網絡、lease接收方的出錯。
對於中心節點異常,比如宕機,只需要在頒發者恢復后,等待一個最大lease期限就可保證所有lease失效;另一方面,頒發者宕機可能使得全部節點沒有lease,系統處於不可用狀態,解決的方法就是使用一個小集群而不是單一節點作為頒發者。
頒發者與被頒發者之間的時鍾可能也存在誤差,只需要頒發者考慮時鍾誤差即可。
lease時間長短一般取經驗值10秒。太短網絡壓力大,太長則收回承諾時間過長影響可用性。
 
應用:
GFS中,Master通過lease機制決定哪個是主副本,lease在給各節點的心跳響應消息中攜帶。收不到心跳時,則等待lease過期,再頒發給其他節點。
Niobe中,主副本持有從副本頒發的lease,當lease過期時,主從分別會在中心節點上標記對方不可用,而中心節點是全局一致的,兩者只有一個會成功。如果主成功了,從不可用,需要重新與主同步才能可用;如果從成功了,則自己成為新主。
chubby中,paxos選主后,從節點會給主頒發lease,在期限內不選其他節點為主。另一方面,主節點給每個client節點發送lease,用於判斷client死活。
zookeeper中,選主不用lease,而是直接發現沒有主則選主。其余和chubby一致。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM