嘗試着論證下使用阻塞日誌場景下,成員變動的正確性(支持變動少數派個成員,不能同時進行上線和下線兩個操做):緩存
1)備機slave收到[Cold,Cnew]的確認條件是要求以前的日誌都已經收到,這樣保證若是[Cold, Cnew]日誌獲得Cold, Cnew兩個集羣的多數派應答,那麼[Cold, Cnew]以前的日誌都已經在Cnew上造成了多數派;性能
2)[Cold, Cnew]和[Cnew]兩條日誌都是阻塞日誌,即集羣工做狀態全部的成員變動日誌都是阻塞日誌。這裏阻塞日誌的概念和日照郵件中指出的是一致的,即備機對收到的比[Cold, Cnew](或[Cnew]) logID大的日誌的確認條件是,備機已收到[Cold, Cnew](或[Cnew])日誌,若是未收到成員變動日誌,備機不會對後續的日誌作確認(能夠先緩存起來,避免再向主機要)。阻塞日誌的實現見後,這樣保證了[Cold, Cnew]以前,[Cold, Cnew]到[Cnew]之間,[Cnew]以後三個區間的日誌對集羣的認知都是一致的,其取得多數派的條件也是一致的,不會出現不一樣server在宕機重啓恢復時,對不一樣日誌所處集羣認知不一致的狀況。 這樣就和raft的成員變動階段保持一致了。日誌
3)阻塞日誌的實現: 每條日誌都有一個專門的狀態,咱們稱做爲mc_term (membership change term),這個值初始是0,leader在發送每一個成員變動日誌時遞增這個mc_term的值,在後續的日誌中都帶新值。 備機會在本地的內存中緩存這個值,備機收到每條日誌都會檢查這個值和本身保存的值,若是收到的值比保存的值大,表示這個日誌以前有副本變動日誌沒有收到,則不會對此日誌作確認。備機會在收到成員變動日誌並落盤,且成員變動日誌和本地保存的mc_term值只差一(避免收到的成員變動日誌不連續)會更新本地緩存的這個mc_term值。因爲備機寫到磁盤的日誌都是能夠被確認的,宕機恢復時,server只須要檢查本身保存的logid最大的日誌便可獲知恢復後這個值是多少,無需再額外保存副本變動日誌作處理; server
4)選舉條件保持和raft一致,取最後一條logid的termID和logID。ip
5)副本變動日誌爲阻塞日誌不會影響可用性,會稍微影響亂序的性能(實際上只在[Cold,Cnew]和[Cnew]這兩個點後續的日誌要求必定的順序性),leader還是要求收到每一條的多數派便可提交。每一個server(不管主備)保存的成員變動日誌都是全的。內存
6)在投票時要求覈對選舉組,及[Cold]能夠給[Cold]/[Cold,Cnew]投票,[Cold, Cnew]能夠給[Cold,Cnew]/[Cnew]投票,反之不成立。這實際上一方面保證選舉組有效,另外一方面保證選出的leader都在更新的選舉組裏。對應到實現上,及一臺Server只給比本身mc_term大於等於的server投票,不會給比本身mc_term小的server投票。集羣
阻塞日誌的概念一樣適用於freeze和checkpoint的實現。ember