主頁 > 後端開發 > 從本地事務到分布式事務,淺談事務的分布式一致性演算法。

從本地事務到分布式事務,淺談事務的分布式一致性演算法。

2021-04-21 06:15:32 後端開發

本地事務(資料庫事務)與ACID

什么是資料庫事務?
事務是一個不可分割的資料庫操作序列,也是資料庫并發控制的基本單位,其執行的結果必須使資料庫從一種一致性狀態變到另一種一致性狀態,
事務是邏輯上的一組操作,要么都執行,要么都不執行,

資料庫事務的四大特性
ACID
原子性A:事務是最小的執行單位,不允許分割,事務的原子性確保動作要么全部完成,要么完全不起作用
一致性C:執行事務前后,資料保持一致,多個事務對同一個資料讀取的結果是相同的
隔離性I:并發訪問資料庫時,一個用戶的事務不被其他事務所干擾,各并發事務之間資料庫是獨立的
持久性D:一個事務被提交之后,它對資料庫中資料的改變是持久的,即使資料庫發生故障也不應該對其有任何影響

原子性和持久性定義了事務的邊界,行為的開始和結束,一致性和隔離性即是對事務中間狀態的管理,

ACID的核心是C,大家都是為得到C而提出的不同緯度的限制和規范
A確定一個功能的完整性,D對狀態負責,I作為C的等級系數,不同的I策略會出現不同的C,
隔離性I的設定就是對一致性不同程度的破壞,事實上,如果我們順序對資料進行讀寫,ACD是完全可以保證的,但這樣效率會非常低下,
選擇合適的隔離策略是為了在一致性和性能之間平衡,取得最好的綜合表現,

一致性作為本地事務的核心,即使從本地事務進化到了分布式事務后,也同樣是作為分布式事務的核心,下文的分布式事務,也將會著重講解一致性,

分布式事務與CAP、BASE理論

什么是分布式事務?
分布式事務是指事務的參與者、支持事務的服務器、資源服務器以及事務管理器分別位于分布式系統的不同節點之上,通常一個分布式事務中會涉及對多個資料源或業務系統的操作,

對于本地事務處理或者是集中式的事務處理系統,很顯然我們可以采用已經被實踐證明很成熟的ACID模型來保證資料的嚴格一致性,
但是隨著分布式事務出現,傳統的單機事務模型已經無法勝任,尤其是對于一個高訪問量、高并發的互聯網分布式系統來說,如果我們期望實作一套嚴格滿足ACID特性的分布式事務,
很可能出現的情況就是在系統的可用性和嚴格一致性之間出現沖突,故產生了CAP定理,

CAP定理

C一致性:所有節點在同一時間具有相同的資料
A可用性:保證每個請求不管成功或者失敗都有回應
P分隔容忍:系統中任意資訊的丟失或失敗不會影響系統的繼續運作
CAP不可能都取,只能取其中兩個
如果C是第一需求的話,那么會影響A的性能,因為要資料同步,不然請求結果會有差異,但是資料同步會消耗時間,可用性就會降低
如果A是第一需求的話,那么只要有一個服務在,就能正常接收請求,但是對回傳結果便不能保證,原因是在分布式部署的時候,資料一致的程序不可能那么快,
如果同時滿足一致性和可用性,就很難保證磁區的容錯,

同時需要明確的一點是,對于一個分布式系統而言,磁區容錯性可以說是一個最基本的要求,
因為既然是一個分布式系統,那么分布式系統中的組件必然需要被部署到不同的節點,否則也就無所謂分布式系統了,因此必然出現子網路,
對于分布式系統而言,網路問題又是一個必定會出現的例外情況,因此磁區容錯性也就成為了一個分布式系統必然需要面對和解決的問題,

Zookeeper&Eureka
Zookeeper:滿足cp,任何時候對Zookeeper的訪問請求都能得到一致的資料結果,同時系統對網路分割具備容錯性,但是Zookeeper不能保證每次服務請求都是可達的,
在使用zookeeper獲取服務串列時,如果此時的zookeeper集群中的leader宕機了,該集群就要進行leader的選舉,又或者zookeeper集群中半數以上服務器節點不可用,那么將無法處理該請求,故zk不能保證服務可用性,

Eureka:滿足ap,eureka server采用peer to peer對等通信,這是一種去中心化的架構,無master/slave之分,每一個peer都是對等的,
在這種架構風格中,節點通過彼此互相注冊來提高可用性,每個節點都可被視為其他節點的副本,只要有一臺eureka還在,就能保證服務可用,只不過查到的資訊可能不是最新的,

BASE理論

BASE是對CAP中一致性和可用性權衡的結果,其來源于對大規模互聯網系統分布式實踐的總結,是基于CAP定理逐步演化而來的,
其核心思想是即使無法做到強一致性,但每個應用都可以根據自身的業務特點,采用適當的方式來使系統達到最終一致性,

Basically Available(基本可用):
基本可用是指分布式系統在出現不可預知故障的時候允許損失部分可用性(絕不等價系統不可用)

Soft state(軟狀態):
弱狀態也稱為軟狀態,和硬狀態相對,是指允許系統中的資料存在中間狀態,并認為該中間狀態的存在不會影響系統的整體可用性,即允許系統在不同節點的資料副本之間進行資料同步程序存在延時,

Eventually consistent(最終一致性):
最終一致性強調的是系統中的所有的資料副本在經過一段時間的同步后,最終能夠達到一個一致的狀態,
因此,最終一致性的本質是需要系統保證最終資料能夠達到一致,而不要實時保證系統資料的強一致性,

BASE理論面向的是大型高可用可擴展的分布式系統,和傳統事務的ACID特性是相反的,它完全不同于ACID的強一致性模型,而是提出通過犧牲強一致性來獲得可用性,并允許資料在一段時間內是不一致的,但最終達到一致狀態,

解決分布式一致性問題--->一致性協議

在分布式系統中,每一個機器節點雖然都能夠明確地知道自己在進行事務操作程序中的結果是成功或失敗,但卻無法直接獲取到其他分布式節點的操作結果,

因此,當一個事務操作需要跨越多個分布式節點的時候,為了保持事務處理的ACID特性,就需要引入一個稱為"協調者"的組件來統一調度所有分布式節點的執行邏輯,
這些被調度的分布式節點則被稱為"參與者",協調者負責調度參與者的行為,并最終決定這些參與者是否要把事務真正進行提交,

基于這個思想,衍生出了二階段提交和三階段提交兩種協議,

2PC

2PC(Two-Phase Commit),二階段提交,為了使基于分布式系統架構下的所有節點在進行事務處理程序中能夠保證原子性和一致性而設計的一種演算法,
目前,絕大部分關系型資料庫都是采用二階段提交協議來完成分布式事務處理的,
二階段提交將一個事務的處理程序分為了投票和執行兩個階段,其核心是對每個事務都采用先嘗試后提交的處理方式,因此也可以將二階段提交看作一個強一致性的演算法,

階段一:提交事務請求

  1. 事務詢問
    協調者向所有參與者發送事務內容,詢問是否可以執行事務提交操作,并開始等待各參與者的相應,
  2. 執行事務
    各參與者節點執行事務操作,并將undo和redo資訊記入事務日志,
  3. 各參與者向協調者反饋事務詢問的回應
    如果參與者成功執行了事務操作,那么就反饋給協調者yes相應,表示事務可以執行;
    如果參與者沒有成功執行事務,那么就反饋給協調者No回應,表示事務不可以執行,
    二階段提交協議的階段一也被稱為"投票階段",即各參與者投票表明是否要繼續執行接下來的事務提交操作,

階段二:執行事務提交
兩種可能:
A. 執行事務提交
假如協調者從所有的參與者獲得的反饋都是yes回應,那么就會執行事務提交,

  1. 發送提交請求
    協調者向所有參與者節點發出Commit請求
  2. 事務提交
    參與者接收到Commit請求后,會正式執行事務提交操作,并在完成提交之后釋放在整個事務執行期間占用的事務資源,
  3. 反饋事務提交結果
    參與者在完成事務提交之后,向協調者發送Ack訊息
  4. 完成事務
    協調者接收到所有參與者反饋的Ack訊息后,完成事務,

B. 中斷事務
假如任何一個參與者向協調者反饋了No相應,或者在等待超時之后,協調者尚無法接收到所有參與者的反饋回應,那么就會中斷事務,

  1. 發送回滾請求
    協調者向所有參與者節點發出RollBack請求
  2. 事務回滾
    參與者接收到Rollback請求后,會利用其在階段一中記錄的Undo資訊來執行事務回滾操作,并在完成回滾之后釋放在整個事務執行期間占用的資源,
  3. 反饋事務回滾結果
    參與者在完成事務回滾之后,向協調者發送Ack訊息
  4. 中斷事務
    協調者接收到所有參與者反饋的Ack訊息后,完成事務中斷,

二階段提交協議的優缺點
優點:原理簡單,實作方便
缺點:

  1. 同步阻塞
    在二階段提交的執行程序中,所有參與該事務操作的邏輯都處于阻塞狀態,也就是說,各個參與者在等待其他參與者回應的程序中,將無法進行其他任何操作,
  2. 單點問題
    協調者的角色在整個二階段提交協議中起到了非常重要的作用,一旦協調者出現問題,那么整個二階段提交流程將無法運轉,
    更為嚴重的是,如果協調者是在階段二中出現問題的話,那么其他參與者將會一直處于鎖定事務資源的狀態中,而無法繼續完成事務操作,
  3. 資料不一致
    在階段二時,當協調者向所有的參與者發送Commit請求之后,發生了區域網路例外或者是協調者尚未發送完Commit請求之前自身發生了崩潰,導致最終只有部分參與者收到了Commit請求,
    于是,這部分收到了Commit請求的參與者就會進行事務的提交,而其他沒有收到Commit請求的參與者則無法進行事務提交,于是整個分布式系統便出現了資料不一致現象,
  4. 太過保守
    二階段提交協議沒有設計較為完善的容錯機制,任何一個節點的失敗都會導致整個事務的失敗,

3PC

3PC(Three-Phase commits):3階段提交,將二階段提交協議的"提交事務請求"程序一分為二,

階段一:CanCommit

  1. 事務詢問
    協調者向所有的參與者發送一個包含事務內容的CanCommit請求,詢問是否可以執行事務提交操作,并開始等待各參與者的回應,
  2. 各參與者向協調者反饋事務訪問的回應,
    參與者在接收到來自協調者的CanCommit請求后,正常情況下,如果其自身認為可以順利執行事務,那么會反饋Yes回應,并進入預備狀態,否則反饋No回應,

階段二:PreCommit
在階段二中,協調者會根據各參與者的反饋情況來決定是否可以進行事務的PreCommit操作,正常情況下,包含兩種可能,

A. 執行事務預提交
假如協調者從所有的參與者獲得的反饋都是Yes回應,那么就會執行事務預提交,

  1. 發送預提交請求
    協調者向所有參與者節點發出preCommit的請求,并進入Prepared階段,
  2. 事務預提交
    參與者接收到preCommit請求后,會執行事務操作,并將Undo和Redo資訊記錄到事務日志中,
  3. 各參與者向協調者反饋事務執行的回應
    如果參與者成功執行了事務操作,那么就會反饋給協調者Ack回應,同時等待最終的指令:提交或中止,

B. 中斷事務
假如任何一個參與者向協調者反饋了No相應,或者再等待超時之后,協調者尚無法接收到所有參與者的反饋回應,那么就會中斷事務,

  1. 發送中斷請求
    協調者向所有參與者節點發出abort請求
  2. 中斷事務
    無論是收到來自協調者的abort請求,或者是在等待協調者請求程序中出現超時,參與者都會中斷事務,

階段三:doCommit
該階段將進行真正的事務提交,會存在以下兩種可能的情況

A. 執行提交

  1. 發送提交請求
    進入這一階段,假設協調者處于正常作業狀態,并且它接收到了來自所有參與者的Ack相應,那么它將從"預提交"狀態轉換到"提交"狀態,并向所有的參與者發送doCommit請求,
  2. 事務提交
    參與者接收到doCommit請求后,會正式執行事務提交操作,并在完成提交之后釋放在整個事務執行期間占用的事務資源,
  3. 反饋事務提交結果
    參與者在完成事務提交之后,向協調者發送Ack訊息
  4. 完成事務
    協調者接收到所有參與者反饋的Ack訊息后,完成事務,

B. 中斷事務
進入這一階段,假設協調者處于正常作業狀態,并且有任何一個參與者向協調者反饋了No相應,或者再等待超時之后,協調者尚無法接收到所有參與者的反饋回應,那么就會中斷事務,

  1. 發送中斷請求
    協調者向所有參與者節點發送abort請求
  2. 事務回滾
    參與者接收到abort請求后,會利用其在階段二中記錄的Undo資訊來執行事務回滾操作,并在完成回滾之后釋放在整個事務執行期間占用的資源,
  3. 反饋事務回滾結果
    參與者在完成事務回滾之后,向協調者發送Ack訊息
  4. 中斷事務
    協調者接收到所有參與者反饋的Ack訊息后,事務中斷

一旦進入階段三,可能會存在以下兩種故障,

  • 協調者出現問題,
  • 協調者和參與者之間的網路出現故障,

無論出現哪種情況,最終都會導致參與者無法及時接收到來自協調者的doCommit或是abort請求,針對這樣的例外情況,參與者都會在等待超時之后,繼續進行事務提交,

優缺點:
優點
相較于二階段提交協議,三階段提交協議最大的優點就是降低了參與者的阻塞反饋,并且能夠在出現單點故障后繼續達成一致,
缺點
在參與者接收到preCommit訊息后,如果網路出現磁區,此時協調者所在的節點和參與者無法進行正常網路通信,在這種情況下,該參與者依然會進行事務的提交,這必然出現資料的不一致性,

Paxos演算法:目前公認的解決分布式一致性問題最有效的演算法之一,(較難以理解 暫時PASS 不做過多決議)

Paxos演算法需要解決的問題就是如何在一個可能發生上述例外的分布式系統中,快速且正確地在集群內部對某個資料的值達成一致,
并且保證不論發生以上任何例外,都不會破壞整個系統的一致性,

ZAB協議

ZAB(Zookeeper Atomic Broadcast),Zookeeper原子訊息廣播協議,Zookeeper資料一致性的核心演算法
ZAB協議是為ZK專門設計的一種支持崩潰服務恢復的原子廣播協議,并未完全采用Paxos演算法,是特別為Zookeeper設計的崩潰可恢復的原子訊息廣播演算法,

基于該協議,Zookeeper實作了一種主備模式的系統架構來保持集群中各副本之間資料的一致性,
具體的,Zookeeper使用一個單一的主執行緒來接收并處理客戶端的所有事務請求,并采用ZAB的原子廣播協議,將服務器資料的狀態變更以事務Proposal的形式廣播到所有的副本行程上去,
ZAB協議的這個主備模型架構保證了同一時刻集群中只能夠有一個主行程來廣播服務器的狀態變更,因此能夠很好的處理客戶端大量的并發請求,

同時,ZAB協議必須能夠保證一個全域的變更序列被順序應用,也就是說,ZAB協議需要保證如果一個狀態變更已經被處理了,那么所有其依賴的狀態變更都應該已經被提前處理掉了,

最后,ZAB協議需要做到在當前主行程出現崩潰退出或重啟現象時,Zookeeper依然能夠正常作業,

ZAB協議的核心:
所有的事務請求必須由一個全域唯一的服務器來協調處理,這樣的服務器被稱為Leader服務器,而余下的其他服務器則成為Follower服務器,
Leader服務器負責將一個客戶端事務請求轉換成一個事務Proposal(提議),并將該Proposal分發給集群中所有的Follower服務器,
之后Leader服務器需要等待所有Follower服務器的反饋,一旦超過半數的Follower服務器進行了正確的反饋后,那么Leader就會再次向所有的Follower服務器分發Commit訊息,要求其將前一個Proposal進行提交,

ZAB協議的兩種基本模式:崩潰恢復、訊息廣播

ZAB協議介紹

ZAB協議包括兩種基本的模式,分別是崩潰恢復和訊息廣播,

  1. 當整個服務框架在啟動程序中,或者是當Leader服務器出現網路中斷、崩潰退出與重啟等例外情況時,ZAB協議就會進入恢復模式并選舉產生新的Leader服務器,
    當選舉產生了新的leader服務器,同時集群中已經有過半的機器與該Leader服務器完成了狀態同步之后,ZAB協議就會退出恢復模式,
    其中,所謂的狀態同步是指資料同步,用來保證集群中存在過半的機器能夠和Leader服務器的資料狀態保持一致,

  2. 當集群中已經有過半的Follower服務器完成了和Leader服務器的狀態同步,那么整個服務框架就可以進入訊息廣播模式了,
    當一臺同樣遵守ZAB協議的服務器啟動后加入到集群中時,如果此時集群中已經存在一個Leader服務器在負責進行訊息廣播,那么新加入的服務器就會自覺地進入資料恢復模式:找到Leader所在的服務器,并與其進行資料同步,然后一起參與到訊息廣播流程中去,

  3. 由于Zookeeper只允許唯一的一個Leader服務器來進行事務請求的處理,Leader服務器在接收到客戶端的事務請求后,會生成對應的事務提案并發起一輪廣播協議;
    如果集群中的其他機器接收到客戶端的事務請求,那么這些非Leader服務器會首先將這個事務請求轉發給Leader服務器,

  4. 當Leader服務器出現崩潰退出或機器重啟,亦或者是集群中已經不存在過半的服務器與該Leader服務器保持正常通信時,
    那么在重新開始新一輪的原子廣播事務操作之前,所有行程首先會使用崩潰恢復協議來使彼此達到一個一致的狀態,于是整個ZAB流程就會從訊息廣播模式進入到崩潰恢復模式,

  5. 一個機器要成為新的Leader,必須獲得過半行程的支持,同時由于每個行程都有可能會崩潰,因此,在ZAB協議運行程序中,前后會出現多個Leader,并且每個行程也有可能會多次成為Leader,
    進入崩潰恢復模式后,只要集群中存在過半的服務器能夠彼此進行正常通信,那么就可以產生一個新的Leader并重新進入訊息廣播模式,

ZAB與Paxos演算法的聯系和區別

聯系:

  1. 兩者都存在一個類似于Leader行程的角色,由其負責協調多個Follower行程的運行,
  2. Leader行程都會等待超過半數的Follower做出正確的反饋后,才會將一個提案進行提交,
  3. 在ZAB協議中,每個Proposal中都包含了一個epoch值,用來代表當前的Leader周期,在Paxos演算法中,同樣存在這樣一個標識,只是名字變成了Ballot,

在Paxos演算法中,一個新選舉產生的主行程會進行兩個階段的作業,第一階段被稱為讀階段,在這個階段中,這個新的主行程會通過和所有其他行程進行通信的方式來收集上一個主行程提出的提案,并將它們提交,第二階段被稱為寫階段,在這個階段,當前主行程開始提出它自己的提案,
在Paxos演算法設計的基礎上,ZAB協議額外添加了一個同步階段,在同步階段之前,ZAB協議也存在一個和Paxos演算法中的讀階段非常類似的程序,稱為發現(Discovery)階段,
在同步階段中,新的Leader會確保存在過半的Follower已經提交了之前Leader周期中的所有事務Proposal,
這一同步階段的引入,能夠有效地保證Leader在新的周期中提出事務Proposal之前,所有的行程都已經完成了對之前所有事務Proposal的提交,
一旦完成同步階段后,那么ZAB就會執行和Paxos演算法類似的寫階段,

ZAB協議和Paxos演算法的本質區別在于,兩者的設計目標不太一樣,
ZAB協議主要用于構建一個高可用的分布式資料主備系統,
Paxos演算法則是用于構建一個分布式的一致性狀態機系統,

Raft演算法

參考原文一文搞懂Raft演算法 :https://www.cnblogs.com/xybaby/p/10124083.html
下文只做筆者個人的一些總結摘要,

Raft是工程上使用較為廣泛的強一致性,去中心化,高可用的分布式協議,Raft是一個共識演算法,所謂共識,就是多個節點對某個事情達成一致的看法,即使是在部分節點故障、網路延時,網路分割的情況下,
在分布式系統中,共識演算法更多用于提高系統的容錯性,比如分布式存盤中的復制集(replication),

Raft的作業原理

Raft會選舉出Leader,leader完全負責replicated log的管理,
Leader負責接受所有客戶端更新請求,然后復制到follower節點,并在"安全"的時候執行這些請求,
如果Leader故障,followers會重新選舉出新的leader,

由此可得Raft涉及的兩個子問題:leader選舉、log復制,

leader選舉

raft協議中,一個節點任一時刻處于以下三個狀態之一:leader、follower、candidate

所有節點啟動時都是follower狀態,在一段時間內如果沒有收到來自leader的心跳,從follower切換到candidate,發起選舉,如果收到majority的造成票(含自己的一票)則切換到leader狀態,如果發現其他節點比自己更新,則主動切換到follower,

總之,系統中最多只有一個leader,如果在一段時間里發現沒有leader,則大家通過選舉-投票選出leader,leader會不停的給follower發心跳訊息,表明自己的存活狀態,
如果leader故障,那么follower會轉換成candidate,重新選出leader,

從上面可以看出,哪個節點做leader是大家投票選舉出來的,每個leader作業一段時間,然后選出新的leader繼續負責,
這跟民主社會的選舉很像,每一屆新的履職期稱之為一屆任期,在raft協議中,也是這樣的,對應的術語叫term,
term(任期)以 election(選舉)開始,然后就是一段或長或短的穩定作業期(normal Operation)同時,任期是遞增的,這就充當了邏輯時鐘的作用;
若沒有選舉出leader就結束了,會發起新的選舉,

如果follower在election timeout內沒有收到來自leader的心跳,(也許此時還沒有選出leader,大家都在等;也許leader掛了;也許只是leader與該follower之間網路故障),則會主動發起選舉,
選舉的程序如下:

  1. 增加節點本地的 current term ,切換到candidate狀態

  2. 投自己一票

  3. 并行給其他節點發送 RequestVote RPCs

  4. 等待其他節點的回復
    在這個程序中,根據來自其他節點的訊息,可能出現三種結果

    • 收到majority的投票(含自己的一票),則贏得選舉,成為leader
    • 被告知別人已當選,那么自行切換到follower
    • 一段時間內沒有收到majority投票,則保持candidate狀態,重新發出選舉

    第一種情況,贏得了選舉之后,新的leader會立刻給所有節點發訊息,廣而告之,避免其余節點觸發新的選舉,在這里,先回到投票者的視角,投票者如何決定是否給一個選舉請求投票呢,有以下約束:
    + 在任一任期內,單個節點最多只能投一票
    + 候選人知道的資訊不能比自己的少(這一部分,后面介紹log replication和safety的時候會詳細介紹)
    + first-come-first-served 先來先得

    第二種情況,比如有三個節點A B C,A B同時發起選舉,而A的選舉訊息先到達C,C給A投了一票,當B的訊息到達C時,已經不能滿足上面提到的第一個約束,即C不會給B投票,而A和B顯然都不會給對方投票,
    A勝出之后,會給B,C發心跳訊息,節點B發現節點A的term不低于自己的term,知道有已經有Leader了,于是轉換成follower,

    第三種情況,沒有任何節點獲得majority投票,即出現平票(split vote)情況,
    如果出現平票(split vote)的情況,那么就延長了系統不可用的時間(沒有leader是不能處理客戶端寫請求的),因此raft引入了randomized election timeouts來盡量避免平票情況,
    同時,leader-based 共識演算法中,節點的數目都是奇數個,盡量保證majority的出現

log復制

當有了leader,系統應該進入對外作業期了,客戶端的一切請求來發送到leader,leader來調度這些并發請求的順序,并且保證leader與followers狀態的一致性,
raft中的做法是,將這些請求以及執行順序告知followers,leader和followers以相同的順序來執行這些請求,保證狀態一致,

共識演算法的實作一般是基于復制狀態機(Replicated state machines),何為復制狀態機:
簡單來說:相同的初識狀態 + 相同的輸入 = 相同的結束狀態,引文中有一個很重要的詞deterministic,就是說不同節點要以相同且確定性的函式來處理輸入,而不要引入一下不確定的值,比如本地時間等,
如何保證所有節點 get the same inputs in the same order,使用replicated log是一個很不錯的注意,log具有持久化、保序的特點,是大多數分布式系統的基石,

因此,可以這么說,在raft中,leader將客戶端請求(command)封裝到一個個log entry,將這些log entries復制(replicate)到所有follower節點,然后大家按相同順序應用(apply)log entry中的command,則狀態肯定是一致的,

請求完整流程如下:
當系統(leader)收到一個來自客戶端的寫請求,到回傳給客戶端,整個程序從leader的視角來看會經歷以下步驟:

  1. leader append log entry
  2. leader issue AppendEntries RPC in parallel
  3. leader wait for majority response
  4. leader apply entry to state machine
  5. leader reply to client
  6. leader notify follower apply log
    可以看到日志的提交程序有點類似兩階段提交(2PC),不過與2PC的區別在于,leader只需要大多數(majority)節點的回復即可,這樣只要超過一半節點處于作業狀態則系統就是可用的,

raft演算法為了保證高可用,并不是強一致性,而是最終一致性,leader會不斷嘗試給follower發log entries,直到所有節點的log entries都相同,

在上面的流程中,leader只需要日志被復制到大多數節點即可向客戶端回傳,一旦向客戶端回傳成功訊息,那么系統就必須保證log(其實是log所包含的command)在任何例外的情況下都不會發生回滾,
這里有兩個詞:commit(committed),apply(applied),前者是指日志被復制到了大多數節點后日志的狀態;而后者則是節點將日志應用到狀態機,真正影響到節點狀態,

safety

衡量一個分布式演算法,有許多屬性,如
safety:nothing bad happens
liveness:something good eventually happens

在任何系統模型下,都需要滿足safety屬性,即在任何情況下,系統都不能出現不可逆的錯誤,也不能向客戶端回傳錯誤的內容,
raft保證被復制到大多數節點的日志不會被回滾,就是safety屬性,而raft最侄訓讓所有節點狀態一致,這屬于liveness,

為了在任何例外情況下系統不出錯,即滿足safety屬性,對leader election,log replication兩個子問題有諸多約束

leader election約束:

  • 同一任期內最多只能投一票,先來先得
  • 選舉人必須比自己知道的更多(比較term,log index)

log replication約束:

  • 一個log被復制到大多數節點,就是committed,保證不會回滾
  • leader一定包含最新的committed log,因此leader只會追加日志,不會洗掉覆寫日志
  • 不同節點,某個位置上日志相同,那么這個位置之前的所有日志一定是相同的
  • Raft never commits log entries from previous terms by counting replicas.

參考文獻

《從PAXOS到ZOOKEEPER分布式一致性原理與實踐》

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/278357.html

標籤:其他

上一篇:python將變數保存成本地檔案以及讀取

下一篇:Python的list方法append和extend有什么區別?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more