raft論文學(xué)習(xí).md

raft

1. 特點(diǎn)

  • strong leader
    raft是強(qiáng)leader算法,日志只從leader分發(fā),使理解更容易
  • leader election
    raft節(jié)點(diǎn)隨機(jī)時間選舉leader,可以快速簡單的處理沖突
  • membership changes
    允許集群在配置更改期間繼續(xù)正常運(yùn)行

2. 一致性算法的典型屬性

  • 永遠(yuǎn)不返回錯誤結(jié)果
  • 只要半數(shù)以上節(jié)點(diǎn)可用,就可以正常工作
  • 它們不依賴于時間來確保日志的一致性:錯誤的時鐘和極端的消息延遲在最壞的情況下會導(dǎo)致可用性問題
  • 一般情況下只要超過半數(shù)節(jié)點(diǎn)通過,就可以成功返回

3 raft概況

同步狀態(tài)機(jī)架構(gòu)圖


image.png

3.1 State

3.1.1 所有節(jié)點(diǎn)都會持久化的狀態(tài)信息

(響應(yīng)rpc前會先持久化)

  • currentTerm
    server的最新term(初始化為0,逐個遞增)
  • votedFor
    在當(dāng)前term中,收到的vote的candidateId
  • log[]
    log entries
    每個entry包含state machine 的操作命令以及收到entry時的term信息

3.1.2 所有節(jié)點(diǎn)都會保存的非持久化信息

  • commitIndex
    最新的log entry index 提交編號(初始化為0,單調(diào)遞增)
  • lastApplied
    最新的應(yīng)用log entry編號(初始化為0,單調(diào)遞增)

3.1.3 leaders才會保存的非持久化信息

(選舉后會重新初始化)

  • nextIndex[]
    要發(fā)送給各個server的log entry的編號(初始化為leader的 last log index+1)
  • matchIndex[]
    每個節(jié)點(diǎn)leader已知已經(jīng)同步的log entry 最大 index (初始化為0,單調(diào)遞增)

3.2 AppendEntries RPC

(leader同步log entry,以及心跳相關(guān)操作)

3.2.1 Arguments

  • term
    leader`s term
  • leaderId
  • prevLogIndex
    緊接在新日志項(xiàng)之前的日志項(xiàng)的索引
  • prevLogTerm
    prevLogIndex 對應(yīng)的term
  • entries[]
    需要持久化的log entry(心跳時為空,同步時為了提升效率也可以一次同步多條 log entry)
  • leaderCommit
    leader`s commitIndex

3.2.2 Results

  • term
    當(dāng)前的term,方便leader紀(jì)錄保存
  • success
    follower如果已經(jīng)同步 prevLogIndex and prevLogTerm的log entry則返回true

3.2.3 Receiver implementation

  • 如果term < currentTerm 返回 false
  • 如果在prevLogIndex對應(yīng)的log中的term不等于prevLogTerm則返回false
  • 如果已經(jīng)存在的entry中與新的log entry沖突(index相同,但是term不同),則刪除已經(jīng)存在的entry,應(yīng)用新的log entry
  • 如果沒有新log對應(yīng)的index,則直接append新增的entries
  • 如果 leaderCommit > commitIndex 則設(shè)置 set commitIndex =
    min(leaderCommit, index of last new entry)

3.3 RequestVote RPC

(candidates 獲取 選舉信息)

3.3.1 arguments

  • term
    candidate`s term
  • candidateId
    發(fā)起選舉的candidateId
  • lastLogIndex
    candidate的最新的log erntry的 index
  • lastLogTerm
    candidate的最新的log entry 的 term

3.3.2 results

  • term
    當(dāng)前的term,方便condidate更新各個節(jié)點(diǎn)的term信息
  • voteGranted
    如果同意選舉 condidate 則返回true

3.3.3 Receiver implementation(返回說明)

  • 如果term 小于currentTerm則返回false
  • 如果votedFor是null或者candidateId,并且candidate’s log同步情況不晚于receiver的log,則返回true

3.4 Rules for Servers

3.4.1 All Servers

  • 如果 commitIndex > lastApplied
    增加lastApplied,并應(yīng)用log[lastApplied]
  • 如果 request or response 包含 term T > currentTerm
    則 set currentTerm = T, convert to follower

3.4.2 Followers

  • Respond to RPCs from candidates and leaders
  • 如果在election timeout時間內(nèi)沒有收到當(dāng)前l(fā)eader發(fā)送的AppendEntries RPC調(diào)用或者candidate的選舉請求,則轉(zhuǎn)為candidate

3.4.3 Candidates

  • 關(guān)于轉(zhuǎn)變?yōu)镃andidate角色后發(fā)起選舉
    • 增加currentTerm
    • 選舉自己為leader
    • 重置election timer
    • 向所有節(jié)點(diǎn)發(fā)送選舉請求RPC
  • 如果過半節(jié)點(diǎn)同意選舉請求,則轉(zhuǎn)換為leader角色
  • 如果收到新leader的AppendEntries則轉(zhuǎn)為follower角色
  • 如果超過 election timeout 則開啟新一輪的選舉

3.4.4 Leaders

  • 選舉為leader
    發(fā)送初始AppendEntries RPCs (heartbeat) 給所有節(jié)點(diǎn),在整個空閑期都發(fā)送,防止有節(jié)點(diǎn)沒收到heartbeat,發(fā)起選舉
  • 收到客戶端命令時
    在本地 append entry log
    等待更新到 state machine后,才返回給客戶端
  • 如果 last log index ≥ nextIndex for a follower
    發(fā)送起始于nextIndex的 AppendEntries RPC with log entries
    • 如果成功,則更新對應(yīng)follower的nextIndex and matchIndex
    • 如果因?yàn)閘og不一致導(dǎo)致失敗,則decrement nextIndex and retry
  • 如果大部分節(jié)點(diǎn)的matchIndex[i] ≥ N, log[N].term == currentTerm 并且 N > commitIndex 則set commitIndex = N

3.5 raft會保證整個生命周期如下的規(guī)則

  • election safety
    在同一個term下,最多選舉出一個leader
  • leader append-only
    leader只會添加log,不會有覆蓋或著刪除操作
  • log matching
    如果兩個log具有相同的term和index,則之前的所有l(wèi)og都會相同
  • leader completeness
    如果一個log entry在一個term下被提交,則任何leader(如果發(fā)生leader選舉)在之后的term中都會包含此log entry
  • state machine safety
    如果server已經(jīng)應(yīng)用某個index下的log entry到state machine,不會有其他的server在相同的index下應(yīng)用不同的log entry

3.6 server節(jié)點(diǎn)角色

image.png

4 raft一致性算法詳細(xì)介紹

raft算法分為三個獨(dú)立的部分:

  • Leader election
    如果當(dāng)前的leader fails時,必須要選舉出一個leader
  • Log replication
    leader接受客戶端的命令,并且同步到整個集群,其他節(jié)點(diǎn)必須與leader數(shù)據(jù)保持一致
  • Safety
    raft主要確保state machine的可靠性:如果任何一個server應(yīng)用一條log entry到 state machine,就確保不會在相同的index下應(yīng)用其他log

以下列出論文中的條目,方便有個全局印象

  • 4.1 Raft basics
  • 4.2 Leader election
  • 4.3 Log replication
  • 4.4 Safety
    • 4.4.1 Election restriction
    • 4.4.2 Committing entries from previous terms
    • 4.4.3 Safety argument
  • 4.5 Follower and candidate crashes
  • 4.6 Timing and availability
    以下分別詳細(xì)介紹

4.1 Raft basics

一般一個raft集群包含5個節(jié)點(diǎn)(可以允許兩個節(jié)點(diǎn)異常),任何時間點(diǎn)下server只會是 leader,follower或者candidate中的一個角色.正常運(yùn)行情況下,只會有一個leader,其他節(jié)點(diǎn)都為follower. follower只會被動接收leader和candidate的request而不會主動發(fā)送請求.leader處理所有客戶端的請求(如果client連接flolower,會轉(zhuǎn)接給leader). candidate用于選舉leader時的中間狀態(tài).
raft會把時間劃分到任意長度的term,term是連續(xù)遞增編號的,最開始的term會先發(fā)起選舉,如果有candidate贏得選舉,則會成為leader,如果選舉沖突,則會在下一個term重新選舉.raft確保在同一個term下,最多有一個leader
term就是raft里的邏輯時鐘,每個server都會保存一個當(dāng)前term值,term會隨著時間遞增.current term信息會在集群內(nèi)不斷交換,如果一個server的current term比其他server小,會更新到較大的那個值,如果一個candidate或leader發(fā)現(xiàn)自己的term是過期的,則會降級為follower,如果server收到term老舊的request,server會拒絕響應(yīng).
raft使用rpc進(jìn)行通信,基本的raft算法只需要兩種rpc服務(wù),RequestVote rpc是在選舉期間由候選人發(fā)起,Append-Entries RPCs 則是由leader發(fā)起的用于replicate log entries 和 heartbeat. raft還有第三種rpc服務(wù)(InstallSnapshot RPC),用于在服務(wù)器之間傳輸快照

4.2 Leader election

raft通過heartbeat機(jī)制觸發(fā)選舉.server啟動時,會作為followers角色,并且只要能夠收到來自leader或candidate有效的rpc請求,server會一直保持followers角色,如果超過election timeout沒有收到heartbeat, 則會認(rèn)為當(dāng)前沒有可用的leader節(jié)點(diǎn),并會發(fā)起選舉.
要發(fā)起選舉,follower會先增加自己的term并且轉(zhuǎn)變?yōu)閏andidate角色,選舉自己為leader,并且并發(fā)的向其他節(jié)點(diǎn)發(fā)起 RequestVote RPCs ,結(jié)果會有三種:
1 自己贏得選舉成為leader
2 其他節(jié)點(diǎn)贏得選舉成為leadder
3 沒有節(jié)點(diǎn)贏得選舉
下面分別探討三種情況

  1. 如果大多數(shù)server選舉的candidate會成為leader,每個server在同一個term下最多給一個server投票(誰先發(fā)起RequestVote,選舉誰),candidate成為leader后,發(fā)送heartbeat給各個節(jié)點(diǎn),防止新的選舉發(fā)生
  2. candidate在等待選舉結(jié)果時,如果收到leader發(fā)送的AppendEntries RPC,并且leader’s term (included in its RPC) 不低于 candidate’s current term,則認(rèn)為leader是合法的,自己降級為follower,如果leader的term低于自己的current term,則會忽略,繼續(xù)保持 candidate 狀態(tài)
  3. 如果多個candidate發(fā)起選舉,并且都沒有能贏得大多數(shù)的投票,則會等待選舉超時后,增加term,發(fā)起新一輪的選舉.

raft使用隨機(jī)的 election timeouts 來避免選舉沖突,一般為150–300ms范圍內(nèi)的隨機(jī)值.相同的機(jī)制用于處理分裂投票道偷。每個候選人在選舉開始時重新啟動隨機(jī)化的選舉超時赋朦,并在開始下一次選舉前等待超時時間的流逝;這減少了在新選舉中再次出現(xiàn)分裂投票的可能性。

4.3 Log replication

leader被選舉出來后,就可以響應(yīng)客戶端的請求.一個client的請求包含一個replicated state machines要執(zhí)行的命令.leader會將命令添加到log , 然后并發(fā)給每個節(jié)點(diǎn)的發(fā)起 AppendEntries RPCs,entry被safely復(fù)制后,leader應(yīng)用entry到state machine中,并返回成功給client.如果followers crash或響應(yīng)慢或者網(wǎng)絡(luò)有問題,leader會不定期重新發(fā)送 Append-Entries RPCs (即使leader 已經(jīng)responded client),直到followers最終存儲所有的log.

log的組織形式如下圖:


image.png

每個log entry包含一個state machine命令以及l(fā)eader接收entry的term編號.log entries中的term可以用來探測不一致.每個log entry還有一個index編號,確認(rèn)在log里的位置.

leader決定何時應(yīng)用log entry到state machine,成為一個提交了的log entry. raft確保已經(jīng)提交的erntry最終會被所有節(jié)點(diǎn)應(yīng)用到可用的state machines.一旦leader將log etnry同步到大多數(shù)節(jié)點(diǎn),該條log就被提交.
raft會維護(hù)如下屬性:

  • 如果兩個log具有相同的index和term,則它們存儲的命令相同
  • 如果兩個log具有相同的index和term,則它們前面的log都相同
    首先leader在每個term的每個log index下最多創(chuàng)建一個entry,并且此后不會在改變,來確保第一個屬性
    其次通過AppendEntries簡單的一致性檢查來確保第二個屬性,leader發(fā)送的AppendEntries RPC中,會包含上一條log entry的index and term ,如果follower沒有找到相同index,term的log,則會refuse新的entry.一致性檢查作為一個歸納步驟:日志的初始空狀態(tài)滿足日志匹配屬性惕蹄,一致性檢查在擴(kuò)展日志時保留日志匹配屬性闭专。因此,每當(dāng)AppendEntries 成功返回時,leader就知道follower的日志與它自己通過新條目的日志是相同的蜻展。
    正確情況下,leader和followers是一致的,AppendEntries的一致性檢查也不會出錯.但是leader可能會導(dǎo)致不一致情況(old leader可能沒有將所有的entry復(fù)制到所有節(jié)點(diǎn)).如下圖所示,因?yàn)橐幌盗械膌eader和follower的 crash,導(dǎo)致數(shù)據(jù)不一致,follower可能相比于leader多或者少數(shù)據(jù).


    image.png

    raft算法中,通過強(qiáng)制follower同步leader的log來處理不一致問題,即follower與leader沖突的log會用leader的log覆蓋(下一節(jié)會探討這樣做的可行性)
    為了修復(fù)不一致數(shù)據(jù),leader必須找到最后一個兩者都agree的log,刪除follower此后的日志,發(fā)送leader此后的log到follower(這些都在AppendEntries RPCs中處理).leader 維護(hù)了 每個folloer的 nextIndex(要發(fā)送的下一條log的index). 一旦選舉出leader后,會初始化所有follower的nextIndex為leader的最后一條log index.如果follower與leader不一致, AppendEntries check則會返回錯誤,leader收到錯誤信息會減少nextIndex并且重試AppendEntries RPC,最終nextIndex會找到leader和follower一致的點(diǎn),然后在刪除沖突entry并且同步leader的log后,AppendEntries返回成功,并且follower與leader達(dá)到一致狀態(tài).

4.4 Safety

本節(jié)通過添加對哪些服務(wù)器可以被選為leader的限制來完成Raft算法。這個限制確保任何給定期限的leader獲得在以前期限中提交的所有條目邀摆。最后纵顾,我們給出了Leader完備性的一個證明圖,并展示了它是如何導(dǎo)致復(fù)制狀態(tài)機(jī)的正確行為的栋盹。

4.4.1 Election restriction

在任何基于領(lǐng)導(dǎo)的協(xié)商一致算法中施逾,領(lǐng)導(dǎo)最終必須存儲所有提交的日志條目。在一些協(xié)商一致的算法中例获,比如Viewstamped Replication[22]汉额,可以選出一個leader,即使它最初不包含所有提交的條目榨汤。這些算法包含額外的機(jī)制來識別缺失的條目蠕搜,并在選舉過程中或選舉后不久將其發(fā)送給新領(lǐng)導(dǎo)人。不幸的是件余,這導(dǎo)致相當(dāng)多的額外機(jī)械和復(fù)雜性讥脐。Raft使用了一種更簡單的方法,它保證所有來自previousterm的提交條目從每個新領(lǐng)導(dǎo)者當(dāng)選的那一刻起就存在啼器,而不需要將這些條目傳遞給領(lǐng)導(dǎo)者旬渠。這意味著日志條目只在一個方向上流動,即從leader到follower端壳。
raft通過在選舉中添加限制來確保只有包含所有已經(jīng)提交的log的節(jié)點(diǎn)才能選舉成功.因?yàn)橐鄶?shù)節(jié)點(diǎn)選舉才能成為leader,至少在其中一個節(jié)點(diǎn)包含所有提交的entry,進(jìn)而,如果candidate比大多數(shù)節(jié)點(diǎn)的log都up-to-date則可以確保該candidate包含所有已經(jīng)提交的信息(如果voter比candidate的log更up-to-date則不會選舉它)
raft通過比較最后一條entry的index和term來判斷哪個更加up-to-date,如果兩個log term不相同,則term較大的更up-to-date,如果term相同,則log越長的越up-to-date

4.4.2 Committing entries from previous terms

舊leader crash之后,新的leader會嘗試在之前的基礎(chǔ)上完成entry的復(fù)制,但是即使大部分節(jié)點(diǎn)同步了一個entry,也不能確定確認(rèn)entry已經(jīng)提交,下圖給出了一種大多數(shù)節(jié)點(diǎn)已經(jīng)同步log的情況下,依然被新leader覆蓋掉的情況(term是基于時間生成的)


image.png

為了避免上面的情況,raft不會根據(jù)已經(jīng)同步的replicas個數(shù)來確認(rèn)是提交.只有l(wèi)eader當(dāng)前term的提交才會根據(jù)是否有大多數(shù)節(jié)點(diǎn)同步,只要當(dāng)前term的entry被提交,則所有之前的entry也可以通過 Log Matching Property來間接保證提交.

4.5 Safety argument

以下通過反證法,證明raft能夠保證數(shù)據(jù)完整性.
假設(shè)leader(leader_T)提交 term T log,但是term T log沒有在新的term的leader(leader_U U>T)中保存,則可以作出如下推測:

  • 在 leader_U選舉時肯定沒有 log T
  • leader_T 同步了log T 到大部分機(jī)器上, 而leader_U是被大部分節(jié)點(diǎn)選舉出來,則最少有一個voter(voter_special)包含log T
  • voter_special在選舉leader_U前,肯定接收到了leader_T的committed entry,否則會
    rejected the AppendEntries request from leader_T
  • voter_special在選舉leader_U時依然會保存有l(wèi)og T
  • voter_special選舉了leader_U, 所以 leader_U的log必須不比voter_special舊,因此只會有如下兩種情況
      1. voter_special和leader_U 最新的term相同, 則leader_U應(yīng)該不少于voter_special的log,應(yīng)該包含 log T
      1. 如果leader_U的log term 比 voter_special大,則之前l(fā)eader_U在同步最新的term時會保證包含所有之前term的數(shù)據(jù)( by the Log Matching Property),即包含 log T

最后,raft要求server按照 log index順序應(yīng)用 log entry,與 State Machine Safety Property 相結(jié)合,共同確保所有節(jié)點(diǎn)的state machines會按照相同的順序應(yīng)用log

4.6 Follower and candidate crashes

如果一個follower或者candidate crash,那么后續(xù)的RequestVote和AppendEntries RPCs 就會失敗,raft會不定期的重試,如果crash的節(jié)點(diǎn)重新啟動,rpc會成功.如果一個server在完成rpc請求,但是在返回成功前crash,則會在重啟后收到一個相同的rpc請求,因?yàn)閞aft的rpc請求是冪等的,所以不用做特殊處理.例如,如果follower收到的AppendEntries請求里的log與當(dāng)前l(fā)og包含一樣的內(nèi)容,節(jié)點(diǎn)會忽略這些entries

4.7 Timing and availability

raft集群必須要滿足如下時間關(guān)系,否則無法正常選主,對外提供服務(wù):
broadcastTime ? electionTimeout ? MTBF
其中:

  • broadcastTime 為發(fā)送rpc并且收到回應(yīng)的平均時間
  • electionTimeout 選舉超時時間
  • MTBF 兩個節(jié)點(diǎn)crash間隔的平均時間
    一般 broadcastTime 為 0.5~20ms
    electionTimeout 因此在10~500ms之間
    MTBF一般為幾個月

5 Cluster membership changes

配置變更時,如果只是簡單的逐個變更,則可能會有同一個term下,兩個主的危險,如下圖所示:


image.png

為了避免上面的問題,raft使用兩階段提交來變更配置,首先切換為變更配置狀態(tài)( joint consensus),joint consensus 提交后,集群使用新的配置,joint consensus combines both the old and new configurations:

  • log entry會被同步到新舊配置的所有節(jié)點(diǎn)
  • 新舊配置中的任何一個節(jié)點(diǎn)都可能作為leader
  • 選舉或著entry的提交需要經(jīng)過新舊配置所有節(jié)點(diǎn)的大多數(shù)通過
    joint consensus 允許允許各個服務(wù)器在不同的時間在不同的配置之間進(jìn)行轉(zhuǎn)換告丢,而不會出現(xiàn)安全隱患。此外损谦,允許集群在整個配置更改期間繼續(xù)為客戶端請求提供服務(wù)岖免。
    Cluster configurations 的存儲和同步使用特殊的一種log entry,下圖描述了configuration change process


    image.png

    leader收到 Cold to Cnew的請求時,會存儲configuration 信息為 joint consensus log entry,并且同步到其他節(jié)點(diǎn),一旦server添加了new configuration entry 到log,未來的decision都會使用這個configuration(server總是使用最新的configuration,不管提交與否),這就意味著,leader會使用Cold,new 來判斷l(xiāng)og entry for Cold,new 是否提交,如果leader crash,新leader的配置可能為 Cold or Cold,new任何情況下Cnew 都無法作出單方面的decisions
    一旦Cold,new提交之后,無論 Cold 或著 Cnew 都無法獨(dú)立的作出decision,Leader Completeness Property 也確保了只有包含 Cold,new log entry 的節(jié)點(diǎn)才會被選舉為leader.此時創(chuàng)建一個Cnew的log entry并同步到其他節(jié)點(diǎn)是安全可靠的,其他節(jié)點(diǎn)同樣一同步到Cnew就生效.只要Cnew被提交,Cold就無關(guān)緊要,Cnew中沒用的節(jié)點(diǎn)就可以shutdown,如上圖所示,Cnew和Cold沒有重疊的時間做decision,因此可以確保安全.
    此外,新增節(jié)點(diǎn)沒有初始化的數(shù)據(jù),可能需要很長時間才能同步數(shù)據(jù),無法提交新的log.未了避免這段 availability gaps,raft引入一個額外的階段( non-voting members, leader只同步log entry到該節(jié)點(diǎn),但是not considered for majorities,直到同步完成).
    第二點(diǎn),舊配置的leader可能在新配置中被排除,這種情況下只要提交了Cnew,就立刻降級(變?yōu)?follower state),這就有一個階段會是leader管理一個不把自己count到majorities 的時間段.Cnew提交后(這之后new configuration才能夠operate independently,之前只有Cold的節(jié)點(diǎn)才能選舉為leader),才會發(fā)生leader的轉(zhuǎn)換.
    第三種情況,可能被刪除的節(jié)點(diǎn)依然存活,因?yàn)椴辉贑new中,不會收到heatbeat,因此會不斷的發(fā)起選舉,損耗性能.為了處理這種情況,節(jié)點(diǎn)如果確信已經(jīng)有l(wèi)eader正常運(yùn)行時會忽略 RequestVote RPCs.此外,如果一個server在minimum election timeout的時間內(nèi)收到當(dāng)前l(fā)eader的 RequestVote RPC也會被忽略,但是這個不會影響正常的選舉,因?yàn)檎5倪x舉流程至少要等一個minimum election timeout

6 log compaction

raft的log會逐漸增長,需要做壓縮清理,Snapshotting是一種最簡便的方式,下圖展示了snapshots的基本流程.


image.png

每個server獨(dú)立的獲取快照,覆蓋已經(jīng)提交的log,主要的工作就是state machine 將當(dāng)前狀態(tài)寫入快照.raft快照中還會包含一部分的metadata,主要為最后一條log的index和term信息,主要是用于AppendEntries的一致性檢查.此外,為了方便 membership changes, snapshot還會包含最新的configuration信息.一旦server完成了snapshot,就可以把之前的log entry和之前的snapshot都給清理掉.
雖然server會各自做snapshot,但是leader還是會偶爾發(fā)送snapshots到有延遲的節(jié)點(diǎn)(發(fā)生在follower延遲較高,leader把它所需要的next log entry已經(jīng)清理的情況下,一般發(fā)生在新加入節(jié)點(diǎn)的情況).
leader會有InstallSnapshot RPC來發(fā)送snapshots給followers,如下圖所示:


image.png

follower收到InstallSnapshot RPC后必須要決定怎么處理現(xiàn)存的log entry.一般是收到的InstallSnapshot RPC中日志比server的新,則server會將之前的log清理掉,如果是當(dāng)前的log已經(jīng)比Snapshot 更新,則將沖突的部分覆蓋清理掉,更新的部分則保留.
還有另外兩個影響快照的問題岳颇。首先,服務(wù)器必須決定何時進(jìn)行快照颅湘。如果服務(wù)器快照太頻繁话侧,就會浪費(fèi)磁盤帶寬和能量;如果快照太不頻繁,就有耗盡存儲容量的風(fēng)險闯参,還會增加重新啟動時重播日志所需的時間瞻鹏。一個簡單的策略是在日志達(dá)到固定大小(以字節(jié)為單位)時捕獲快照。如果將此大小設(shè)置為比快照的預(yù)期大小大得多鹿寨,那么用于快照的磁盤帶寬開銷將很小新博。
第二個問題是,編寫快照可能會花費(fèi)大量時間脚草,我們不希望這會延遲正常的操作赫悄。解決方案是使用即寫即拷技術(shù),這樣就可以接受新的更新馏慨,而不會影響正在寫入的快照埂淮。例如,使用 functional data structures構(gòu)建的state machines 自然支持這一點(diǎn)熏纯⊥耄或者粤策,操作系統(tǒng)的寫時復(fù)制支持(例如樟澜,Linux上的fork)可以用來創(chuàng)建整個狀態(tài)機(jī)的內(nèi)存快照(我們的實(shí)現(xiàn)使用這種方法)。

7 Client interaction

如果client發(fā)送請求到raft集群后,raft已經(jīng)提交,但是leader在返回response給client前crash,則client會任務(wù)沒有提交成功,則會重新在新的leader上再此執(zhí)行導(dǎo)致錯誤.因此client會給每個command一個唯一的編號,state machine在處理請求時也會保存每個client對應(yīng)的編號,如果收到command的編號已經(jīng)執(zhí)行過,則會直接返回,防止再次執(zhí)行.
在做讀操作的時候因?yàn)闆]有寫操作,client連接的leader時是無法確認(rèn)這個leader是否已經(jīng)被排除,已經(jīng)選舉出來新的leader,因此需要額外工作,確保數(shù)據(jù)是否為最新.

  • 響應(yīng)請求前,leader會提交一個blank no-op entry log 來開始一個term,確保當(dāng)前l(fā)eader是正常的
  • raft會先檢查是否大多數(shù)節(jié)點(diǎn)的heartbeta message正常響應(yīng),之后才會返回結(jié)果

參考

https://raft.github.io/raft.pdf

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末叮盘,一起剝皮案震驚了整個濱河市秩贰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柔吼,老刑警劉巖毒费,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異愈魏,居然都是意外死亡觅玻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門培漏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來溪厘,“玉大人,你說我怎么就攤上這事牌柄』” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵珊佣,是天一觀的道長蹋宦。 經(jīng)常有香客問我披粟,道長,這世上最難降的妖魔是什么冷冗? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任守屉,我火速辦了婚禮,結(jié)果婚禮上蒿辙,老公的妹妹穿的比我還像新娘胸梆。我一直安慰自己,他們只是感情好须板,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布碰镜。 她就那樣靜靜地躺著,像睡著了一般习瑰。 火紅的嫁衣襯著肌膚如雪绪颖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天甜奄,我揣著相機(jī)與錄音柠横,去河邊找鬼。 笑死课兄,一個胖子當(dāng)著我的面吹牛牍氛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播烟阐,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼搬俊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蜒茄?” 一聲冷哼從身側(cè)響起唉擂,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎檀葛,沒想到半個月后玩祟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屿聋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年空扎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片润讥。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡转锈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出象对,到底是詐尸還是另有隱情黑忱,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站甫煞,受9級特大地震影響菇曲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抚吠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一常潮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧楷力,春花似錦喊式、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至检柬,卻和暖如春献联,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背何址。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工里逆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人用爪。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓原押,卻偏偏與公主長得像,于是被迫代替她去往敵國和親偎血。 傳聞我的和親對象是個殘疾皇子诸衔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355