日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一致性协议raft详解(二):安全性

發布時間:2024/2/28 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一致性协议raft详解(二):安全性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一致性協議raft詳解(二):安全性

    • 前言
    • 安全性
      • log recovery
        • 為什么no-op能解決不一致的問題?
    • 成員變更
      • Single mempership change
    • raft用到的隨機時間
    • raft 腦裂
      • 數據到達 Leader 節點前
      • 數據到達 Leader 節點,但未復制到 Follower 節點
      • 數據到達 Leader 節點,成功復制到 Follower 所有節點,但還未向 Leader 響應接收
      • 數據到達 Leader 節點,成功復制到 Follower 部分節點,但還未向 Leader 響應接收

前言

有關一致性協議的資料網上有很多,當然錯誤也有很多。筆者在學習的過程中走了不少彎路。現在回過頭來看,最好的學習資料就是Leslie LamportDiego Ongaro的數篇論文、Ongaro在youtube上發的三個視頻講解,以及何登成的ppt。

本系列文章是只是筆者在學習一致性協議過程中的摘抄和總結,有疏漏之處敬請諒解,歡迎討論。

安全性

raft的log replication機制并不能充分的保證每一個狀態機會按照相同的順序執行相同的指令。例如,一個follower可能會進入不可用狀態同時leader已經提交了若干的日志條目,然后這個follower可能會被選舉為leader并且覆蓋這些日志條目;因此,不同的狀態機可能會執行不同的指令序列

我們通過在leader election增加限制來完善raft算法。在任何基于leader的一致性算法中,leader都必須存儲所有已經提交的日志條目(或者通過額外的機制保證leader丟失的日志條目可以同步給leader)。Raft 使用了一種更加簡單的方法,它可以保證所有之前的任期號中已經提交的日志條目在選舉的時候都會出現在新的leader中,不需要傳送這些日志條目給leader。這意味著日志條目的傳送是單向的,只從leader傳給跟隨者,并且leader從不會覆蓋自身本地日志中已經存在的條目。

**由于raft節點中的日志是順序添加的,那么raft在leader election的時候通過比較兩份日志中最后一條日志目錄的索引號index和任期號term,就可以判斷出誰的日志更新。**只有最新的人才有權利作為leader。候選人為了贏得選舉必須聯系集群中的大部分節點,這意味著每一個已經提交額度日志條目至少會存在于這些節點中的至少一個上。如果候選人的日志至少和大多數的服務器節點一樣新,那么他一定持有了所有已經提交的日志條目

log recovery

以下摘自baidu braft文章

Log Recovery這里分為current Term修復和prev Term修復,Log Recovery就是要保證一定已經Committed的數據不會丟失,未Committed的數據轉變為Committed,但不會因為修復過程中斷又重啟而影響節點之間一致性。

  • current Term修復主要是解決某些Follower節點重啟加入集群,或者是新增Follower節點加入集群,Leader需要向Follower節點傳輸漏掉的Log Entry,如果Follower需要的Log Entry已經在Leader上Log Compaction清除掉了,Leader需要將上一個Snapshot和其后的Log Entry傳輸給Follower節點。
  • prev Term修復主要是在保證Leader切換前后數據的一致性。通過上面RAFT的選主可以看出,每次選舉出來的Leader一定包含已經committed的數據(抽屜原理,選舉出來的Leader是多數中數據最新的,一定包含已經在多數節點上commit的數據),新的Leader將會覆蓋其他節點上不一致的數據。雖然新選舉出來的Leader一定包括上一個Term的Leader已經Committed的Log Entry,但是可能也包含上一個Term的Leader未Committed的Log Entry。這部分Log Entry需要轉變為Committed,相對比較麻煩,需要考慮Leader多次切換且未完成Log Recovery,需要保證最終提案是一致的,確定的。 **RAFT中增加了一個約束:對于之前Term的未Committed數據,修復到多數節點,且在新的Term下至少有一條新的Log Entry被復制或修復到多數節點之后,才能認為之前未Committed的Log Entry轉為Committed。**下圖就是一個prev Term Recovery的過程:

  • S1是Term2的Leader,將LogEntry部分復制到S1和S2的2號位置,然后Crash。
  • S5被S3、S4和S5選為Term3的Leader,并只寫入一條LogEntry到本地,然后Crash。
  • S1被S1、S2和S3選為Term4的Leader,并將2號位置的數據修復到S3,達到多數;并在本地寫入一條Log Entry,然后Crash。
  • 這個時候2號位置的Log Entry雖然已經被復制到多數節點上,但是并不是Committed
  • S5被S3、S4和S5選為Term5的Leader,將本地2號位置Term3寫入的數據復制到其他節點,覆蓋S1、S2、S3上Term2寫入的數據
  • S1被S1、S2、S3選為Term5的Leader,將3號位置Term4寫入的數據復制到S2、S3,使得2號位置Term2寫入的數據變為Committed
  • 為了避免4-1中的現象,協議又強化了一個限制:

    • 只有當前 Term 的 LogEntry 提交條件為:滿足多數派響應之后(一半以上節點 Append LogEntry 到日志)設置為 commit;
    • 前一輪 Term 未 Commit 的 LogEntry 的 Commit 依賴于高輪 Term LogEntry 的 Commit。

    也就是說,我們要通過提交 NO-OP LogEntry 提交系統可用性

    在 Leader 通過競選剛剛成為 Leader 的時候,有一些等待提交的 LogEntry (即 SN > CommitPt 的 LogEntry),有可能是 Commit 的,也有可能是未 Commit 的(PS: 因為在 Raft 協議中 CommitPt 不用實時刷盤)。

    所以為了防止出現非線性一致性(Non Linearizable Consistency);即之前已經響應客戶端的已經 Commit 的請求回退,并且為了避免出現上面4-1中的 Corner Case(已經commit的日志被覆蓋),往往我們需要通過下一個 Term 的 LogEntry 的 Commit 來實現之前的 Term 的 LogEntry 的 Commit (隱式commit),才能保障提供線性一致性。

    但是有可能接下來的客戶端的寫請求不能及時到達,那么為了保障 Leader 快速提供讀服務,系統可首先發送一個 no-op LogEntry 來保障快速進入正常可讀狀態。

    為什么no-op能解決不一致的問題?

    剛當選的leader發送no-op,如果這個no-op可以commit成功那么可以認為這個節點之前所有的日志都已經commit成功了。換句話說,大部分節點已經將當前這個leader寫入了log中。

    也就是說,通過這個no-op commit,我們commit了leader節點上所有的log。就算后面再有figure8中的覆蓋問題,覆蓋的也是這個no-op

    詳情可以看我寫的另外一篇文章:raft引入no-op解決了什么問題

    成員變更

    一文看盡 Raft 一致性協議的關鍵點

  • 可從數學上嚴格證明,只要每次只允許增加或刪除一個成員,Cold與Cnew不可能形成兩個不相交的多數派。這種方式比較簡單,也是etcd的做法。

  • 如果每次增加超過兩個。會導致變更過程中出現多個多數派,所以要引入用兩階段成員變更

  • 系統狀態變化同paxos一樣通過日志同步

  • add node

  • catch up

  • transition Cold和Cnew需要同時達成多數派,log replication才算是成功。

  • Single mempership change

    論文中提以下幾個關鍵點:

  • 由于 Single 方式無論如何 Cold 和 CNew 都會相交,所以 Raft 采用了直接提交一個特殊的 replicated LogEntry 的方式來進行 single 集群關系變更
  • 跟普通的 LogEntry 提交的不同點,configuration LogEntry 不需要 commit 就生效,只需要 append 到 Log 中即可。( PS: 原文 “The New configuration takes effect on each server as soon as it is added to the server’s log”)。
  • 后一輪 MemberShip Change 的開始必須在前一輪 MemberShip Change Commit 之后進行,以避免出現多個 Leader 的問題。
  • 注意:

  • 后一輪 MemberShip Change 的開始必須在前一輪 MemberShip Change Commit 之后進行
  • 提交特殊的 replicated LogEntry不需要commit(不需要形成多數派),只要有一條日志被commit了,整個系統后續也認為這條日志已經apply成功了。
  • raft用到的隨機時間

  • raft leader的任期是隨機時間(一般情況下不需要指定leader的任期,因為term變動會導致系統不可服務)
  • Raft 算法使用隨機選舉超時時間的方法來確保很少會發生選票瓜分的情況,每一任期已經投票的follower節點在過了選舉超時時間之后(或者節點剛起來的時候,會等待隨機的時間才變為candidate),會變為candidate,并向向其他節點發送requestVote。
  • 每一個candidate在開始一次選舉的時候會重置一個隨機的選舉超時時間,然后在超時時間內等待投票的結果。
  • raft 腦裂

    Raft 協議強依賴 Leader 節點的可用性來確保集群數據的一致性。數據的流向只能從 Leader 節點向 Follower 節點轉移。當 Client 向集群 Leader 節點提交數據后,Leader 節點接收到的數據處于未提交狀態(Uncommitted),接著 Leader 節點會并發向所有 Follower 節點復制數據并等待接收響應,確保至少集群中超過半數節點已接收到數據后再向 Client 確認數據已接收。一旦向 Client 發出數據接收 Ack 響應后,表明此時數據狀態進入已提交(Committed),Leader 節點再向 Follower 節點發通知告知該數據狀態已提交。

    在這個過程中,主節點可能在任意階段掛掉,看下 Raft 協議如何針對不同階段保障數據一致性的。

    數據到達 Leader 節點前

    這個階段 Leader 掛掉不影響一致性,不多說。

    數據到達 Leader 節點,但未復制到 Follower 節點

    這個階段 Leader 掛掉,數據屬于未提交狀態,Client 不會收到 Ack 會認為超時失敗可安全發起重試。Follower 節點上沒有該數據,重新選主后 Client 重試重新提交可成功。原來的 Leader 節點恢復后作為 Follower 加入集群重新從當前任期的新 Leader 處同步數據,強制保持和 Leader 數據一致。

    數據到達 Leader 節點,成功復制到 Follower 所有節點,但還未向 Leader 響應接收

    這個階段 Leader 掛掉,雖然數據在 Follower 節點處于未提交狀態(Uncommitted)但保持一致,重新選出 Leader 后可完成數據提交,此時 Client 由于不知到底提交成功沒有,可重試提交。針對這種情況 Raft 要求 RPC 請求實現冪等性idempotent),也就是要實現內部去重機制(client如果發了個請求,就要一直無限重試知道成功,并且raft集群也會在自己恢復之前嘗試commit但是可能因為節點crash沒有commit成功的log(Figure 8)。也就是說raft節點會忽略自己已經commit的log的rpc請求,直接返回成功?)。

    數據到達 Leader 節點,成功復制到 Follower 部分節點,但還未向 Leader 響應接收

    這個階段 Leader 掛掉,數據在 Follower 節點處于未提交狀態(Uncommitted)且不一致,Raft 協議要求投票只能投給擁有最新數據的節點。所以擁有最新數據的節點會被選為 Leader 再強制同步數據到 Follower,數據不會丟失并最終一致。

    疑問

  • Q: uncommitted日志會作為當前的log entry被保存嗎?A: 會的,應該沒有commit rpc整個系統就可以運轉正常了。
  • Q: 什么時候回復client?A: leader append log entry 之后應該就可以回了,如果除了leader已經有超過半數寫入了,那么不到半數也能回
  • 總結

    以上是生活随笔為你收集整理的一致性协议raft详解(二):安全性的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。