分布式系統中主要的問題就是如何保持節點狀態的一致性,不論發生任何failure,只要集群中大部分的節點可以正常工作,則這些節點具有相同的狀態,保持一致,在client看來相當於一台機器。
一致性問題本質就是replicated state machines,即所有結點都從同乙個state出發,都經過同樣的一些操作序列(log),最後到達同樣的state。其中保證各個節點執行相同的操作序列就是raft演算法所要實現的。在raft演算法中有乙個leader的角色,client與之進行互動,並且leader協調follower,保障所有的follower具有相同的操作序列,最後提交這些操作,使狀態機達成乙個新的一致的stat。
整個raft演算法分為leader選舉,日誌分發,日誌壓縮(快照),集群成員變更。其中的leader選舉是演算法的核心部分。演算法保證任何時候最多只有乙個leader,但是可能沒有
leader(比如正在選舉過程中或者集群成員多數不可用時)。在leader確立之後,就可以進行日誌分發,演算法保證日誌會被安全的分發到集群中並且應用到狀態機的日誌和自己相同。快照是為了減少日誌量,去除中間過程。集群成員變更是為了在不停服務的情況下安全使用新的集群配置。
raft在非拜占庭錯誤情況下,包括網路延遲、分割槽、丟包、冗餘和亂序等錯誤都可以保證正確,不會返回錯誤結果,這就是安全性保證。實際上就是保證所有成員狀態機都以同樣的順序,執行同樣的命令。下面分析幾種典型的場景下,raft是如何保證安全性的 官網:www.fhadmin.org 。
1. leader選舉之後,如果follower與leader日誌有衝突該如何處理?
raft規定follower中的衝突日誌會被leader中的日誌覆蓋,使得follower中的日誌總是與leader的日誌保持一致。leader必須找到follower日誌中最後兩者達成一致的地方,然後刪除從那個點之後的所有日誌條目,傳送自己的日誌給follower。所有的這些操作都在進行日誌複製rpc的一致性檢查時完成: leader針對每乙個follower維護了乙個 nextindex,表示下乙個需要傳送給follower的日誌條目的index。當乙個leader剛獲得權力的時候,他初始化所有的 nextindex 值為自己的最後一條日誌的index加1。leader每次傳送日誌複製rpc的時候會包含兩個值:prevlogindex和prevlogterm,分別對應緊隨新日誌條目之前日誌的索引值(index)和任期號(term),即prevlogindex = newindex - 1,如果follower在它的日誌中找不到包含leader傳送過來的index和term的條目,那麼他就會拒絕接收新的日誌條目。也就是此時follower的日誌和leader不一致,日誌複製rpc 時的一致性檢查就會失敗。在被follower拒絕之後,leader就會減小 nextindex 值並進行重試。最終 nextindex 會在某個位置使得leader和follower的日誌達成一致。當這種情況發生,日誌複製 rpc 就會成功,這時就會把follower衝突的日誌條目全部刪除並且加上leader的日誌。一旦日誌複製 rpc 成功,那麼follower的日誌就會和leader保持一致,並且在接下來的任期裡一直繼續保持。通過上述步驟,raft演算法保證了日誌是順序複製的。就是說,假如有一條舊的日誌還未複製給followera,那麼更新的日誌就不能複製。日誌的順序複製,很大程度上簡化了raft演算法。比如檢視各成員日誌的新舊,只要比較最後一條日誌即可。
2. 如果在乙個follower宕機的時候leader提交了若干的日誌條目,然後這個follower上
線後可能會被選舉為leader並且覆蓋這些日誌條目,如此就會產生不一致。
raft通過對leader的選舉進行限制,來保證所新選出的任何leader對於給定的任期號,都擁有了之前任期的所有被提交的日誌條目,限制規則為:candidate傳送出去的投票請求訊息必須帶上其最後一條日誌條目的index與term;接收者需要判斷該index與term至少與本地日誌的最後一條日誌條目一樣新,否則不給投票。因為 前乙個leader提交日誌條目的條件是日誌複製給集群中的多數成員,candidate選舉為leader的條件也是需要多數成員的投票。那麼這兩個大多數中成員必定有乙個交叉,即有乙個成員具有該日誌,並且投票給了新leader,也就意味著新leader的日誌至少不比該成員舊,那麼新leader也具有該日誌。這樣就得到證明了,後續的leader一定具有前面leader提交的日誌。
3. 即使保證上述選舉規則,也不能保證一致性,也就是說會出現leader提交了前面任期的日誌條目之後,該條目還有可能被後來的leader覆蓋而產生不一致。如下圖所示:
如果上述情況(c)中,term=2,index=2的日誌條目被複製到大多數後,如果此時當選的s1提交了該日誌條目,則後續產生的term=3,index=2會覆蓋它,此時就可能會在同乙個index位置先後提交乙個不同的日誌,這就違反了狀態機安全性,產生不一致。也就是說當乙個新leader當選時,由於所有成員的日誌進度不同,很可能需要繼續複製前面term的日誌條目,就算複製到多數伺服器並且提交,還是可能被覆蓋,因為前面term對應的日誌條目較舊,容易使的沒有這些條目的其他伺服器當選leader,此時就會覆蓋這些日誌條目。
為了消除上述場景就規定leader可以複製前面任期的日誌,但是不會主動提交前面任期的日誌。而是通過提交當前任期的日誌,而間接地提交前面任期的日誌。
4.配置變更的時候,需要保證任何時候只能有乙個leader,直接從舊的配置轉化到新配置的方案是不安全的,如下圖所示:
轉換過程中,server1,server2通過舊配置選出乙個leader(三颱中的兩台支援),server3,server4,server5通過新配置選出乙個leader(五颱中的三颱支援),這樣在同乙個term中就有兩台leader,造成不一致,為了保證安全性,配置更改必須使用兩階段方法。在 raft 中,集群先切換到乙個過渡配置,我們稱之為共同一致;一旦共同一致已經被提交了,那麼系統就切換到新的配置上。
過渡配置保證不會在old與new兩個配置上同時產生leader :
過渡配置是指由 old配置和 new復合成的乙個新配置(old+new)。
leader會將該過渡配置日誌先應用到本地,然後複製給集群中的所有成員。所有收到配置的成員,會直接將配置應用到本地。
處於過渡配置的成員,在leader選舉與提交日誌時規則發生了變化,要求分別得到old與new兩個配置下的多數成員同意才行。比如:
old:1、2、3
new:2、3、4、5、6 (刪除機器1,增加機器4、5、6)
old+new:1、2、3、4、5、6(機器是old+new所有機器)
那麼處於過渡配置的成員在leader選舉與提交日誌時,需要得到 old(1、2、3)三個成員中的多數支援,以及new(2、3、4、5、6)五個成員中的多數支援(而不是old+new中六個成員的多數)。
那麼上述過度配置如何保證不同時間段只產生乙個leader:
1)從old -> old+new配置提交之前
此時還未產生new配置,因此不可能在new配置下產生leader。
那麼是否可能在old與old+new下分別產生leader哪? old下要產生leader需要old中的多數投票,old+new下要產生leader也需要old中的多數投票,而要在old與old+new下分別產生leader,則old中至少有乙個成員同時投票給old與old+new中的leader。根據投票規則,在乙個term下只能投票一次,因此就不可能在old與old+new配置下在同乙個term上分別產生leader。
而在不同term下產生則不違反規則,因為新的term下產生的leader,傳送心跳給舊leader,舊leader就會馬上變成follower。
2)old+new提交之後
只要old+new這個配置提交,則意味著該配置已經複製給了old中的多數成員,那麼在old配置中就不可能再產生乙個leader出來了。只能在old+new與new配置下產生。而在old+new與new中也不可能在同乙個term下分別選舉出leader,這個證明與old與old+new配置是一樣的。
若每次增加或者刪除乙個成員不需要過渡配置:
就是說,每次配置變更只能增加或者刪除乙個成員。若滿足則可以直接從old配置轉換到new配置。
證明:舊配置有n個成員,新配置有n+1個成員,在切換過程中不會在舊配置與新配置下分別產生leader。
1)若舊配置下選舉出leader,那麼需要n/2+1個成員投票。
2)新配置下,從成員數是n+1去掉以及投票的n/2+1個成員只剩下n/2個成員。
3)而新配置下要選舉出leader需要(n+1)/2+1=n/2+3/2個成員投票,但是只剩下n/2個成員可以投票,因此新配置下不可能再選舉出leader。
4)反過來也一樣。
如何保證資料安全性? 討論
1 是資料本身的安全。主要是指採用現代密碼演算法對資料進行主動保護,如資料保密 資料完整性 雙向強身份認證等 2 是資料防護的安全。主要是採用現代資訊儲存手段對資料進行主動防護,如通過磁碟陣列 資料備份 異地容災等手段保證資料的安全,資料安全是一種主動的包含措施,資料本身的安全必須基於可靠的加密演算...
低層協議的安全性
ip arp tcp udp icmp dns 路由協議 dhcp協議的缺陷,容易受到的攻擊,以及防禦措施 1 易被攻擊者監聽 竊取 加密 2 沒 淨荷傳輸的完整性 可以應用完整性檢測技術 4 攻擊者利用ip資料報分段在包過濾器注入大量病態小資料報 防火牆可以重組資料報,並檢查內容 1 arp欺騙,...
java 如何保證介面的安全性
根據使用者名稱或者使用者id,結合使用者的ip或者裝置號,生成乙個token。在請求後台,後台獲取http的head中的token,校驗是否合法 和資料庫或者redis中記錄的是否一致,在登入或者初始化的時候,存入資料庫 redis 在使用base64方式的編碼後,token字串還是有20多位,有的...