本文編寫的目的:為了深入理解后期關于zookeeper的文章,本文這里對分布式一致性算法的由來以及要解決的問題做一個簡述,更加深入的原理性東西后續將會以專輯的形式撰寫。另該文比較長,建議收藏閱讀
本文編寫的順序:從集中式演化到分布式--->分布式出現的一些問題--->如何解決這些問題(即最重要的一致性問題)---->事務(保證一致性的方法)---->從早期的ACID到CAP/BASE理論---->2pc/3pc----->Paxos算法
背景
20世紀60年代大型主機被發明出來以后,集中式的計算機系統架構成為了主流,其單機處理能力方面的優勢非常明顯,但從20世紀80年代之后,傳統的集中式處理模式越來越不能滿足人們的需求,同時集中式系統有明顯的單點故障問題,從2008年開始,阿里開啟了“去IOE”計劃,后來逐漸的往分布式系統的方向發展。
分布式系統是一個硬件或軟件組件分布在不同的網路計算機上,彼此之間僅僅通過消息傳遞進行通信和協調的系統。因此分布式系統具有以下幾個特點:
分布性
多臺計算機在空間上隨意分布,同時分布情況也會隨時變動
對等性
集群中的每個節點角色都是一樣的,注意副本的概念
并發性
多個機器可能會同時操作一個數據庫或存儲系統,可能會引起數據不一致問題
缺乏全局時鐘
分布式系統中的多個主機事件先后順序很難界定
故障總發生
服務器宕機,網絡擁堵和延遲
同時和分布式系統進行對比發現集中式系統具有以下幾個特點:
- 部署結構簡單
- 成本高
- 單點故障
- 大型主機的性能擴展受限于摩爾定律
注意:這里要區分集群和分布式的概念,集群是指大量的機器做同一件事情;分布式是指每臺機器都有不同的角色,做不同的事情
分布式異常問題
分布式系統體系結構從出現到現在仍有很多的問題,這里列出一些典型的問題
通信異常
從集中式向分布式演變,必然會引入網絡因素,由于網絡的不可靠性,必然會在分布式節點之間出現網絡 異常的情況
網絡分區
網絡分區也就是常說的腦裂,即出現多個局部小集群,每個局部網絡可以互相通信
三態
三態指的是三種狀態,即成功、失敗、超時;在集中式系統中只有成功和失敗,而超時是由于分布式系統中會出現網絡異常才會有的狀態
節點故障
分布式節點總會出現宕機或者僵死現象
數據丟失
對于有狀態的節點,數據丟失意味著狀態丟失,通常只能從其他節點讀取,恢復存儲的狀態;通常針對這種問題,通過引入副本機制就可以解決
衡量分布式系統的性能
- 性能
- 即系統吞吐能力、響應延遲、QPS等
- 可用性
- 可擴展性
- 一致性
一致性模型
分布式環境下,一致性指的是數據在多個副本之間是否能夠保持一致的特性,對于一個將數據副本分布在不同節點的系統上來說,如果對一個節點的數據進行了更新操作,卻沒有使得第二個節點上的數據得到響應的更新,那么此時在讀取第二個節點的數據時,將會出現臟讀現象(即數據不一致).那么一致性又分為以下幾種:
強一致性
即寫操作完成后,讀操作一定能夠讀到最新的數據,在分布式場景下,很難實現;Paxos、Quorum機制、ZAB協議能夠實現,后面會對這幾種協議算法進行講解。
弱一致性
不承諾立即可以讀到寫入的值,也不承諾多久后能達到數據一致,但會盡可能保證某個時間級別后,數據達到一致狀態
讀寫一致性
用戶讀取自己寫入結果的一致性,保證用戶能夠第一時間看到自己更新的內容;這種實現的解決方案有:
一種方案是對于特定的內容,我們去主庫查詢
設置一個更新時間窗口,在剛更新的一段時間內,默認去主庫讀取,過了這個窗口后,挑選最近更新的從庫進行讀取
直接記錄用戶更新的時間戳,在請求的時候把這個時間戳帶上,凡是最后更新時間小于這個時間戳的從庫都不響應
單調讀一致性
本地讀到的數據不比上次讀到的舊,多次刷新返回舊數據會出現靈異事件,對于這種情況可以通過hash映射到同一臺機器上
因果一致性
如果節點A在更新完某個數據后通知了節點B,那么節點B之后對該數據的訪問和修改基于A更新的值。此時,和節點A無因果關系的節點C的數據訪問則沒有這樣的限制
最終一致性
所有分布式一致性模型中最弱的。不考慮中間的任何狀態,只保證經過一段時間之后,最終系統內數據正確,最大程度上保證了系統的并發能力,因此在高并發場景下,也是使用最廣的一致性模型
事務
事務是可以保證一致性的方法,在集中式系統架構中可以通過ACID的方式實現,在早期分布式架構,是通過CAP/BASE理論來實現的,后來又演化出了2pc/3pc,以及Paxos、Raft等算法來保證一致性。
事務是由一系列對系統中數據進行訪問與更新的操作所組成的一個程序執行邏輯單元。(概念性的東西直接略過~)
-
ACID
-
Atomicity原子性
簡單說就是一個操作序列要么全部成功執行,要么全部不執行
-
Consistency一致性
也就是說數據從一個一致性狀態轉變到另一個一致性狀態,中間不能存在不一致的狀態
-
Isolation隔離性
在并發環境下,一個事務的執行不能被其他事務所干擾,每個事務都有各自獨立完整的數據空間,也就是說一個事務內部的操作以及數據的使用對其他并發的事務都是隔離的。
根據隔離性的強度分為4個級別:
-
未授權讀取(讀未提交)
這是隔離級別最低的。比如說事務A和事務B同時進行,事務A在整個執行的過程中,會將某個數據值從1開始做加法操作直到變成10之后提交事務,而此時事務B能夠看到事務A操作這個數據的所有變化(即從1到10的變化),而這一系列中間值的讀取就是未授權讀取
-
授權讀取(讀已提交)
只允許讀取已經被提交的數據而且不可重復讀。比如說事務A和事務B同時進行,同樣進行加法操作(從1到10),那么此時事務B是無法看到所有的中間值,只能看到最終的10.
-
可重復讀取
在保證事務處理的過程中,多次讀取同一個數據時候,它的值和事務開始時刻是一致的,可能會出現幻影數據(即同一個事務操作,在前后兩個時間段內執行對同一個數據項進行讀取,可能會得到不同的結果),還是拿上面的例子,事務B在第一次事務讀取的時候,始終讀到的是1,但是到第二次事務讀取的時候就會變成了10(因為這個時候事務A已經完成了)
-
串行化
即所有的事務串行執行
-
Durability持久性
即一個事務一旦提交,對應數據的狀態變更就是永久性的
-
-
CAP
-
Consistency一致性
數據在多個副本之間是否能夠保持一致的特性。
-
Avaliabilty可用性
指系統提供的服務必須一直處于可用的狀態,對于用戶的操作總能給在有限的時間內返回結果,這里要注意下是在有限的時間內哦
-
Partition tolerance分區容錯性
即分布式系統在遇到網絡分區的時候,仍然能夠保證對外提供滿足一致性和可用性的服務,除非整個網絡發生了故障
注意:分布式系統無法滿足上面三個特性,但是一定要有分布容錯性,即P,C和A根據需求進行衡量
-
-
BASE
-
Basically Avaliable 基本可用
即分布式系統中在出現故障的時候,允許損失部分可用性,比如響應時間上的損失或者功能上的損失,例如雙11的時候,可以將一些無關緊要的服務進行降級
-
Soft state軟狀態
即允許系統中的數據存在中間狀態,且中間狀態的存在不會影響系統的整個可用性,即允許系統在不同節點的數據副本之間進行數據同步的過程出現延時
-
Eventually consistent最終一致性
強調的是系統中所有的數據副本,在經過一段時間的同步后,最終達到一個一致的狀態
-
分布式一致性協議算
-
2pc
即二階段提交,絕大部分的關系型數據庫都是采用二階段提交協議來完成分布式事務處理。即將事務的提交過程分為了兩個階段來處理
[圖片上傳中...(2pc.png-4fad1c-1597757563590-0)]
-
階段一:請求/表決階段
-
1.事務詢問
協調者向參與者發起事務內容,詢問是否可以執行事務操作,并等待響應
-
2.執行事務
各參與者執行事務操作,并將undo和redo信息記錄到事務日志中
-
3.各參與者向協調者反饋事務詢問的響應
協調者根據所有的參與者是否都響應了yes或者no來進行表決事務是否執行或者不執行
-
-
階段二:提交/執行/回滾階段
-
情況1.執行事務提交
-
1.發起提交請求
協調者向參與者發起commit請求
-
2.事務提交
參與者收到commit請求后,正式執行事務提交,完成之后釋放資源
-
3.反饋事務提交結果
參與者完成事務之后,向協調者發送ack消息
-
4.完成事務
協調者收到所有參與者返回的ack消息,完成事務
-
-
-
情況2.中斷事務
-
1.發送回滾請求
協調者向參與者發起rollback請求
-
2.事務回滾
參與者收到rollback請求后,利用undo信息執行事務回滾操作,完成之后釋放資源
-
3.反饋事務回滾結果
參與者完成事務之后,向協調者發送ack
-
4.中斷事務
協調者接收到所有參與者反饋的ack,完成事務中斷
-
-
二階段提交的問題
-
1.性能問題
從流程上看,在執行過程中節點都處于阻塞狀態。各個操作數據庫的節點都占用數據庫資源,只有當所有節點準備完畢后,事務協調者才會通知進行全局commit/rollback,參與者進行本地事務commit/rollback之后才會釋放資源,對性能影響較大
-
2.單點故障問題
事務協調者是整個分布式事務的核心,一旦事務協調者出現故障,會導致參與者收不到commit/rollback的通知,從而導致參與者節點一直處于事務無法完成的中間狀態
-
3.數據不一致
在第二階段的時候,如果發生局部網絡問題,一部分事務參與者收不到commit/rollback消息,就會導致節點間數據不一致
-
4.太多保守
必須 收到所有參與的正反饋才提交事務如果有任意一個事務參與者的響應沒有收到,則整個事務失敗回滾
-
-
3pc
基于2pc出現的一些問題,3pc進行了改進,也就是三階段提交,將2pc的第二個階段進行了一份為二,形成了CanCommit(提交詢問)、Precommit(預提交)、doCommit階段(最終提交)三個階段;其實3pc和2pc的不同點在于3pc增加了超時機制。
-
階段1:CanCommit(提交詢問)
-
1.事務詢問
協調者向所有參與者發送一個請求,詢問是否可以執行事務提交操作,然后開始等待所有響應者的響應
-
2.各參與者向協調者反饋事務詢問的響應
正常情況下,所有參與者會反饋yes,然后進入預備狀態,否則反饋No
-
-
階段2:PreCommit(預提交)
-
情況1:執行事務預提交(即所有參與者都響應yes)
-
1.發起預提交請求
協調者向所有參與者發出preCommit請求,并進入準備階段
-
2.事務預提交
參與者接收到preCommit請求后,執行事務操作,然后將undo和redo信息記錄到事務日志中
3.各參與者向協調者反饋事務執行的響應
-
-
情況2:中斷事務(任何一個參與者反饋no或者超時就會中斷事務)
- 1.發送中斷請求
- 2.中斷事務
-
-
階段3:doCommit(最終提交)
- 情況1:執行提交
- 1.發送提交請求
- 2.事務提交
- 3.反饋事務提交結果
- 4.完成事務
- 情況2:中斷事務
- 1.發送中斷請求
- 2.事務回滾
- 3.反饋事務回滾結果
- 4.中斷事務
- 情況1:執行提交
-
3pc特點
1.降低了參與者阻塞范圍,增加了超時自動處理的機制
2.能夠在出現單點故障后繼續保持一致
-
3.網絡分區會出現不一致的問題
即參與者接收到了preCommit消息后,出現了網絡分區,即協調者和參與者無法進行正常通信,這個時候該參與者依然會進行事務的提交,就會出現數據不一致的情況
-
Paxos
Paxos算法要解決的問題就是如何保證數據一致性,這是一種基于消息傳遞且具有高度容錯特的一致性算法
首先要引入拜占庭問題
拜占庭問題:即不同軍隊的將軍之間必須制定一個統一的行動計劃,但是在地理上都是分隔開來的,只能依靠通訊員進行通信,但是通訊員可能會存在叛徒,對消息進行篡改,從而欺騙將軍。
這種消息篡改的情況在同一個局域網內幾乎不會出現,或者簡單通過校驗算法進行避免。但是在實際工程實踐中,可以假設不存在拜占庭問題,基于這種假設如何保證一致性呢?這個時候又引入Paxos的故事
古希臘有一個Paxos小島,島上采用會議的形式來通過法令,議會上的議員通過信使來傳遞消息,注意信使和議員都是兼職的,有可能隨時會離開議會,而且信使有可能會重復傳遞消息,也有可能一去不返。那么在這種情況下議會協議也要保證法令能夠正確選舉出來,而且不會產生沖突。
根據這個故事也就衍生出了Paxos算法,該算法有3個角色:
- 1.Proposer(提議者,用來發起提案的,相當于zk中的leader角色)
- 2.Acceptor(接受者,可以接受或拒絕提案,相當于zk中的follower角色)
- 3.Learner(學習者,學習被選定的提案,相當于zk中的observer角色)
注意這里講解的是Basic Paxos,基于Baisc Paxos演化出了Multi Paxos,這里不做過多講解,有興趣的同學可自行查閱
大致流程就是首先選舉出一個Leader,也就是Proposer用來發起提案,然后發送給所有的Acceptor來進行投票,當超過一半投通過票的時候,該提案也就通過了,那么這個時候Proposer會將該提案進行同步所有機器進行學習
也就是說Paxos是基于議會制,以少數服從多數的核心思想來保證一致性的
-
Raft
該算法不做過多講解,想要了解,請查看http://thesecretlivesofdata.com/raft/網址
Raft算法是一個分布式共識算法,有三個角色
1.Leader
-
2.follower
如果follower接收不到leader的心跳時,會變為candidate(這里會有150s~300s的等待時間),發起投票是否成為新的leader
3.candidate(候選人)
核心思想:少數服從多數!
-
ZAB協議
zookeeper是基于該協議(zookeeper原子廣播協議)實現的。這里只做簡單介紹,該協議比較重要,后面會和zookeeper相關文章結合單獨進行講解!
該協議有兩種模式:
1.奔潰恢復
2.消息廣播
它和Paxos的區別聯系在于:
- 1.都存在類似于Leader角色,負責協調多個Follower進程的運行
- 2.Leader進程都會等待超過半數的Follower做出正確反饋后,才會將一個提案進行提交
- 3.zab協議中,每個proposal都包含一個epoch值,用了代表當前Leader周期;Paxos中也存在同樣的標識,名字為Ballot
- 4.zab協議主要用于構建一個高可用的分布數數據主備系統
- 5.Paxos算法主要用于構建一個分布式的一致性狀態機系統
后期將持續更新文章,更多喜歡請關注公眾號"初學大數據"