分布式理論知識
1、分布式系統架構
1.1基礎概念
分布式 : 將一個單體項目分成很多個模塊,各個模塊協同工作,各個模塊構成了分布式系統
集群:針對單個模塊或者單個系統在多臺服務器上部署,稱為集群。為了提高系統的可用性,增加系統的負載。
1.2分布式系統演變









1.3分布式系統面臨的問題
問題描述通信異常網絡本身的不可靠性,因此每次網絡通信都會伴隨著網絡不可用的風險(光纖、路由、DNS等硬件設備或系統的不可用),都會導致最終分布式系統無法順利進行一次網絡通信,另外,即使分布式系統各節點之間的網絡通信能夠正常執行,其延時也會大于單機操作,存在巨大的延時差別,也會影響消息的收發過程,因此消息丟失和消息延遲變的非常普遍。網絡分區網絡之間出現了網絡不連通,但各個子網絡的內部網絡是正常的,從而導致整個系統的網絡環境被切分成了若干個孤立的區域,分布式系統就會出現局部小集群,在極端情況下,這些小集群會獨立完成原本需要整個分布式系統才能完成的功能,包括數據的事務處理,這就對分布式一致性提出非常大的挑戰。節點故障節點故障是分布式系統下另一個比較常見的問題,指的是組成分布式系統的服務器節點出現的宕機或"僵死"現象,根據經驗來說,每個節點都有可能出現故障,并且經常發生。三態分布式系統每一次請求與響應存在特有的“三態”概念,即成功、失敗和超時。分布式系統中,由于網絡是不可靠的,雖然絕大部分情況下,網絡通信能夠接收到成功或失敗的響應,但當網絡出現異常的情況下,就會出現超時現象,通常有以下兩種情況:1. 由于網絡原因,該請求并沒有被成功的發送到接收方,而是在發送過程就發生了丟失現象。2. 該請求成功的被接收方接收后,并進行了處理,但在響應反饋給發送方過程中,發生了消息丟失現象。
1.4分布式系統一致性問題
1.4.1概念
分布式數據一致性指的是數據在多份副本中存儲時,各副本中的數據是一致的。
1.4.2副本數據一致性
分布式系統當中,數據往往會有多個副本。如果是一臺數據庫處理所有的數據請求,那么通過ACID四原則,基本可以保證數據的一致性。而多個副本就需要保證數據會有多份拷貝,這就帶來了同步的問題,因為我們幾乎沒有辦法保證可以同時更新所有機器當中的包括備份所有數據。
網絡延遲,即使我在同一時間給所有機器發送了更新數據的請求,也不能保證這些請求被響應的時間保持一致存在時間差,就會存在某些機器之間的數據不一致的情況。

總得來說,我們無法找到一種能夠滿足分布式系統所有系統屬性的分布式一致性解決方案。因此,如何既保證數據的一致性,同時又不影響系統運行的性能,是每一個分布式系統都需要重點考慮和權衡的。于是,一致性級別由此誕生。
1.4.3一致性分類
強一致性:
這種一致性級別是最符合用戶直覺的,它要求系統寫入什么,讀出來的也會是什么,用戶體驗好,但實現起來往往對系統的性能影響大。但是強一致性很難實現。
弱一致性:
這種一致性級別約束了系統在寫入成功后,不承諾立即可以讀到寫入的值,也不承諾多久之后數據能夠達到一致,但會盡可能地保證到某個時間級別(比如秒級別)后,數據能夠達到一致狀態。弱一致性可以分為
1、讀寫一致性
用戶讀取自己寫入結果的一致性,保證用戶永遠能夠第一時間看到自己更新的內容。比如我們發一條朋友圈,朋友圈的內容是不是第一時間被朋友看見不重要,但是一定要顯示在自己的列表上。
解決方案:
方案1:直接讀主庫。 (問題主庫壓力大)。
方案2:我們設置一個更新時間窗口,在剛剛更新的一段時間內,我們默認都從主庫讀取,過了這個窗口之后,我們會挑選最近有過更新的從庫進行讀取
方案3:我們直接記錄用戶更新的時間戳,在請求的時候把這個時間戳帶上,凡是最后更新時間小于這個時間戳的從庫都不予以響應。
2、單調讀一致性
本次讀到的數據不能比上次讀到的舊?!井a生原因是不同從庫上數據更新有延遲導致的】
由于主從節點更新數據的時間不一致,導致用戶在不停地刷新的時候,有時候能刷出來,再次刷新之后會發現數據不見了,再刷新又可能再刷出來,就好像遇見靈異事件一樣
解決方案:就是根據用戶ID計算一個hash值,再通過hash值映射到機器。同一個用戶不管怎么刷新,都只會被映射到同一臺機器上。這樣就保證了不會讀到其他從庫的內容,帶來用戶體驗不好的影響。
3、因果一致性
指的是:如果節點 A 在更新完某個數據后通知了節點 B,那么節點 B 之后對該數據的訪問和修改都是基于 A 更新后的值。于此同時,和節點 A 無因果關系的節點 C 的數據訪問則沒有這樣的限制。
4、最終一致性
最終一致性是所有分布式一致性模型當中最弱的??梢哉J為是沒有任何優化的“最”弱一致性,它的意思是說,我不考慮所有的中間狀態的影響,只保證當沒有新的更新之后,經過一段時間之后,最終系統內所有副本的數據是正確的。
它最大程度上保證了系統的并發能力,也因此,在高并發的場景下,它也是使用最廣的一致性模型。
1.5CAP定理
CAP 理論含義是,一個分布式系統不可能同時滿足一致性(C:Consistency),可用性(A: Availability)和分區容錯性(P:Partition tolerance)這三個基本需求,最多只能同時滿足其中的2個。
選項描述C(Consistency) 一致性分布式系統當中的一致性指的是所有節點的數據一致,或者說是所有副本的數據一致A (Availability)可用性Reads and writes always succeed. 也就是說系統一直可用,而且服務一直保持正常P (Partition tolerance)分區容錯性系統在遇到一些節點或者網絡分區故障的時候,仍然能夠提供滿足一致性和可用性的服務
舉個場景來說明CAP:

Consistency-一致性
一致性是在寫操作后進行讀操作可以讀到最新的數據狀態,當數據分布在多個節點上時,從任意節點讀取到的數據都是最新的。
商品信息讀寫要滿足一致性需要實現如下目標:
1.商品服務寫入主數據庫成功, 則想從數據庫查詢數據也成功
2.商品服務寫入主數據庫失敗,則向從數據庫查詢也失敗
實現:
1.寫入主數據庫后要數據同步到從數據庫
2.寫入主數據庫后,在向從數據庫同步期間要將從數據庫鎖定, 等待同步完成后在釋放鎖,以免在寫新數據后,向從數據庫查詢到舊的數據。
分布式一致性的特點:
1.由于存在數據庫同步過程,寫操作的響應會有一定的延遲。
2.為了保定數據的一致性,對資源暫時鎖定,待數據同步完成后釋放鎖定資源。
3.如果請求數據同步失敗的節點則會返回錯誤信息, 一定不會返回舊數據。
Availability-可用性
可用性是指任何操作都可以得到響應的結果,且不會出現響應超時或響應錯誤。
商品信息讀寫要滿足可用性需要實現如下目標:
1.從數據庫接收到數據庫查詢的請求則立即能夠響應數據查詢結果
2.從數據庫不允許出現響應超時或錯誤
實現:
1.寫入主數據庫后要將數據同步到從數據。
2.由于要保證數據庫的可用性,不可以將數據庫中資源鎖定。
3.即使數據還沒有同步過來,從數據庫也要返回查詢數據, 哪怕是舊數據,但不能返回錯誤和超時。
Partition tolerance-分區容錯性
分布式系統的各個節點部署在不同的子網中, 不可避免的會出現由于網絡問題導致節點之間通信失敗,此時仍可以對外提供服務, 這個就是分區容錯性 (分區容忍性)。
商品信息讀寫要滿足分區容錯性需要實現如下目標:
1.主數據庫想從數據庫同步數據失敗不形象寫操作
2.其中一個節點掛掉不會影響另一個節點對外提供服務
實現:
1.盡量使用異步取代同步操作,舉例 使用異步方式將數據從主數據庫同步到從數據庫, 這樣節點之間能有效的實現松耦合;
2.添加數據庫節點,其中一個從節點掛掉,由其他從節點提供服務
在實際系統中CAP是不能同時滿足的,思考為啥不能同時滿足CAP?
回答:假設有一個系統如下:

有用戶向Node1發送了請求更改了數據,將數據庫從V0更新成了V1。由于網絡斷開,所以Node2數據庫依然是V0,如果這個時候有一個請求發給了Node2,但是Node2并沒有辦法可以直接給出最新的結果V1, 這個時候該怎么辦呢?
這個時候無法兩種方法,一種是將錯就錯,將錯誤的V0數據返回給用戶。第二種是阻塞等待,等待網絡通信恢復,Node2中的數據更新之后再返回給用戶。顯然前者犧牲了一致性,后者犧牲了可用性。
這個例子雖然簡單,但是說明的內容卻很重要。在分布式系統當中,CAP三個特性我們是無法同時滿足的,必然要舍棄一個。三者舍棄一個,顯然排列組合一共有三種可能。
結論:在分布式系統中只能保證CP、AP,根據不同的系統選擇不同的實現方案。
1.6BASE理論
1.6.1概念
BASE:全稱:Basically Available(基本可用),Soft state(軟狀態),和 Eventually consistent(最終一致性)三個短語的縮寫,來自 ebay 的架構師提出。
BASE是對CAP中一致性和可用性權衡的結果,BASE理論的核心思想是:即使無法做到強一致性,但每個應用都可以根據自身業務特點,采用適當的方式來使系統達到最終一致性。
1.6.2各個理論詳解
1、Basically Available(基本可用)
基本可用是指分布式系統在出現不可預知故障的時候,允許損失部分可用性——但請注意,這絕不等價于系統不可用。比如:響應時間上的損失:正常情況下,一個在線搜索引擎需要在0.5秒之內返回給用戶相應的查詢結果,但由于出現故障(比如系統部分機房發生斷電或斷網故障),查詢結果的響應時間增加到了1~2秒。
2、Soft state(軟狀態)
什么是軟狀態呢?相對于一致性,要求多個節點的數據副本都是一致的,這是一種 “硬狀態”。
軟狀態指的是允許系統中的數據存在中間狀態,并認為該狀態不影響系統的整體可用性,即允許系統在多個不同節點的數據副本之間進行數據同步的過程中存在延遲。
3、Eventually consistent(最終一致性)
最終一致性強調的是系統中所有的數據副本,在經過一段時間的同步后,最終能夠達到一個一致的狀態。因此最終一致性的本質是需要系統保證最終數據能夠達到一致,而不需要實時保證系統數據的強一致性。
1.7一致性協議2PC
在了解2PC之前了解下分布式事務概念,分布式事務從實質上看與數據庫事務的概念是一致的,既然是事務也就需要滿足事務的基本特性(ACID),只是分布式事務相對于本地事務而言其表現形式有很大的不同。
1.7.1概念
2PC ( Two-Phase Commit縮寫)即兩階段提交協議,是將整個事務流程分為兩個階段,準備階段(Prepare
phase)、提交階段(commit phase),2是指兩個階段,P是指準備階段,C是指提交階段。(準備、提交協議)
在計算機中部分關系數據庫如Oracle、MySQL支持兩階段提交協議.

兩個階段過程:
1. 準備階段(Prepare phase):事務管理器給每個參與者發送Prepare消息,每個數據庫參與者在本地執行事務,并寫本地的Undo/Redo日志,此時事務沒有提交。 (Undo日志是記錄修改前的數據,用于數據庫回滾,Redo日志是記錄修改后的數據,用于提交事務后寫入數 據文件)
2. 提交階段(commit phase):如果事務管理器收到了參與者的執行失敗或者超時消息時,直接給每個參與者發送回滾(Rollback)消息;否則,發送提交(Commit)消息;參與者根據事務管理器的指令執行提交或者回滾操作,并釋放事務處理過程中使用的鎖資源。注意:必須在最后階段釋放鎖資源。
1.7.2執行流程
場景一 執行成功提交流程

說明:ACK 確認字符,在數據通信中,接收站發給發送站的一種傳輸類控制字符。表示發來的數據已確認接收無誤。
階段一
1. 事務詢問:協調者向所有的參與者發送事務內容,詢問是否可以執行事務提交操作,并開始等待各參與者的響應。
2. 執行事務 (寫本地的Undo/Redo日志)
3. 各參與者向協調者反饋事務詢問的響應
總結: 各個參與者進行投票是否讓事務進行
階段二
1. 發送提交請求:協調者向所有參與者發出 commit 請求。
2. 事務提交: 參與者收到 commit 請求后,會正式執行事務提交操作,并在完成提交之后釋放整個事務執行期間占用的事務資源。
3. 反饋事務提交結果: 參與者在完成事務提交之后,向協調者發送 Ack 信息。
4. 完成事務: 協調者接收到所有參與者反饋的 Ack 信息后,完成事務
場景二執行失敗事務中斷流程

階段一 也是準備階段,跟成功時候的準備階段一致。
階段二
1. 發送回滾請求: 協調者向所有參與者發出 Rollback 請求。
2. 事務回滾: 參與者接收到 Rollback 請求后,會利用其在階段一中記錄的 Undo 信息來執行事務回滾操作,并在完成回滾之后釋放在整個事務執行期間占用的資源。
3. 反饋事務回滾結果: 參與者在完成事務回滾之后,向協調者發送 Ack 信息。
4. 中斷事務: 協調者接收到所有參與者反饋的 Ack 信息后,完成事務中斷。從上面的邏輯可以看出,二階段提交就做了2個事情:投票,執行。
1.7.3 2PC總結
優點:原理簡單,實現方便。
缺點:同步阻塞,單點問題,數據不一致,過于保守
同步阻塞:二階段提交協議存在最明顯也是最大的一個問題就是同步阻塞,在二階段提交的執行過程中,所有參與該事務操作的邏輯都處于阻塞狀態,也就是說,各個參與者在等待其他參與者響應的過程中,無法進行其他操作。這種同步阻塞極大的限制了分布式系統的性能。
單點問題:協調者在整個二階段提交過程中很重要,如果協調者在提交階段出現問題,那么整個流程將無法運轉,更重要的是:其他參與者將會處于一直鎖定事務資源的狀態中,而無法繼續完成事務操作。
數據不一致:假設當協調者向所有的參與者發送 commit 請求之后,發生了局部網絡異常或者是協調者在尚未發送完所有 commit請求之前自身發生了崩潰,導致最終只有部分參與者收到了 commit 請求。這將導致嚴重的數據不一致問題。
過于保守:如果在二階段提交的提交詢問階段中,參與者出現故障而導致協調者始終無法獲取到所有參與者的響應信息的話,這時協調者只能依靠其自身的超時機制來判斷是否需要中斷事務,顯然,這種策略過于保守。換句話說,二階段提交協議沒有設計較為完善的容錯機制,任意一個節點失敗都會導致整個事務的失敗。
1.8一致性協議3PC
1.8.1概念
3PC,全稱 “three phase commit”,是 2PC 的改進版,將 2PC 的 “提交事務請求” 過程一分為二,共形成了由CanCommit、PreCommit和doCommit三個階段組成的事務處理協議。

1.8.2 3PC流程說明
階段一CanCommit
① 事務詢問:協調者向所有的參與者發送一個包含事務內容的canCommit請求,詢問是否可以執行事務提交操作,并開始等待各參與者的響應。
② 各參與者向協調者反饋事務詢問的響應:參與者在接收到來自協調者的包含了事務內容的canCommit請求后,正常情況下,如果自身認為可以順利執行事務,則反饋Yes響應,并進入預備狀態,否則反饋No響應。

階段二:PreCommit
協調者在得到所有參與者的響應之后,會根據結果有2種執行操作的情況:執行事務預提交,或者中斷事務假如所有參與反饋的都是Yes,那么就會執行事務預提交。
執行事務的話分為3個步驟:
① 發送預提交請求:協調者向所有參與者節點發出preCommit請求,并進入prepared階段。
② 事務預提交:參與者接收到preCommit請求后,會執行事務操作,并將Undo和Redo信息記錄到事務日志中。
③ 各參與者向協調者反饋事務執行的結果:若參與者成功執行了事務操作,那么反饋Ack
如果任何一個參與者反饋了No響應之后則就會中斷事務。
中斷事務分為2個步驟:
① 發送中斷請求:協調者向所有參與者發出abort請求。
② 中斷事務:無論是收到來自協調者的abort請求或者等待協調者請求過程中超時,參與者都會中斷事務。
階段三:do Commit

該階段做真正的事務提交或者完成事務回滾,所以就會出現兩種情況:
場景一執行事務提交:
① 發送提交請求:進入這一階段,假設協調者處于正常工作狀態,并且它接收到了來自所有參與者的Ack響應,那么他將從預提交狀態轉化為提交狀態,并向所有的參與者發送doCommit請求。
② 事務提交:參與者接收到doCommit請求后,會正式執行事務提交操作,并在完成提交之后釋放整個事務執行過程中占用的事務資源。
③ 反饋事務提交結果:參與者在完成事務提交后,向協調者發送Ack響應。
④ 完成事務:協調者接收到所有參與者反饋的Ack消息后,完成事務。
場景二中斷事務
① 發送中斷請求:協調者向所有的參與者節點發送abort請求。
② 事務回滾:參與者收到abort請求后,會根據記錄的Undo信息來執行事務回滾,并在完成回滾之后釋放整個事務執行期間占用的資源。
③ 反饋事務回滾結果:參與者在完成事務回滾后,向協調者發送Ack消息。
④ 中斷事務:協調者接收到所有參與者反饋的Ack消息后,中斷事務。
注意
一旦進入階段三,可能會出現 2 種故障:
1. 協調者出現問題
2. 協調者和參與者之間的網絡故障
如果出現了任何一種情況,最終都會導致參與者無法收到 doCommit 請求或者 abort 請求,針 這種情
況,參與者都會在等待超時之后,繼續進行事務提交。
1.8.3 2PC與3PC對比
1、首先對于協調者和參與者都設置了超時機制(在2PC中,只有協調者擁有超時機制,即如果在一定時間內沒有收到參與者的消息則默認失?。?主要是避免了參與者在長時間無法與協調者節點通訊(協調者掛掉了)的情況下,無法釋放資源的問題,因為參與者自身擁有超時機制會在超時后,自動進行本地commit從而進行釋放資源。而這種機制也側面降低了整個事務的阻塞時間和范圍。
2、通過CanCommit、PreCommit、DoCommit三個階段的設計,相較于2PC而言,多設置了一個緩沖階段保證了在最后提交階段之前各參與節點的狀態是一致的 。
3、PreCommit是一個緩沖,保證了在最后提交階段之前各參與節點的狀態是一致的。但是3PC協議并沒有完全解決數據不一致問題。