極客時間之《分佈式技術原理與算法》筆記

文|Seraph

分佈式知識體系圖
在一定資源上,進行一定通信,通過一定計算,完成一定數據的加工和處理,從而對外提供特定的服務

01 | 分佈式緣何而起:從單兵,到游擊隊,到集團軍

  1. 單機模式:性能受限、存在單點失效問題。
    在這裏插入圖片描述
  2. 游擊隊模式:數據並行或數據分佈式
    第一步:將應用與數據分離
    在這裏插入圖片描述
    第二步:對數據進行拆分
    在這裏插入圖片描述
    存在的問題及解決辦法:
  • 負載均衡:解決不同服務器效率不一致問題。
  • IO讀寫分離:解決數據庫的IO訪問成爲瓶頸的問題。
  • 緩存機制:解決熱點數據訪問頻繁問題。

主要的問題:對提升單個任務的執行性能及降低時延無效。(如單個任務比較複雜時,但執行次數少)

  1. 集團軍模式:任務並行或任務分佈式
    在這裏插入圖片描述
    面臨的問題:設計比較複雜。

  2. 分佈式其實就是將相同或相關的程序運行在多臺計算機上,從而實現特定目標的一種計算方式。產生分佈式的最主要驅動力量,是我們對於性能、可用性及可擴展性的不懈追求。

  3. 採用數據並行還是任務並行?
    任務執行時間短,數據規模大、類型相同且無依賴,則可採用數據並行;如果任務複雜、執行時間長,且任務可拆分爲多個子任務,則考慮任務並行。

02 | 分佈式系統的指標:啥是分佈式的三圍

  1. 分佈式的目的是用更多的機器,處理更多的數據和更復雜的任務。性能、資源、可用性和可擴展性是分佈式系統的重要指標。
  2. 性能指標:吞吐量(Throughput)、響應時間(Response Time)和完成時間(Turnaround Time))。
  3. 吞吐量指標有 QPS(Queries Per Second)、TPS(Transactions Per Second)和 BPS(Bits Per Second)
  4. 一個系統在沒有任何負載時的資源佔用,叫做空載資源佔用,體現了這個系統自身的資源佔用情況。對於同樣的功能,空載資源佔用越少,說明系統設計越優秀,越容易被用戶接受。
  5. 一個系統滿額負載時的資源佔用,叫做滿載資源佔用,體現了這個系統全力運行時佔用資源的情況,也體現了系統的處理能力。
  6. 系統的可用性可以用系統停止服務的時間與總的時間之比衡量。除此之外,系統的可用性還可以用某功能的失敗次數與總的請求次數之比來衡量。
  7. 可靠性通常用來表示一個系統完全不出故障的概率,更多地用在硬件領域。而可用性則更多的是指在允許部分組件失效的情況下,一個系統對外仍能正常提供服務的概率。
  8. 可擴展性,指的是分佈式系統通過擴展集羣機器規模提高系統性能 (吞吐、響應時間、 完成時間)、存儲容量、計算能力的特性,是分佈式系統的特有性質。
  9. 垂直 / 縱向擴展指的是,增加單機的硬件能力,比如 CPU 增強、內存增大等;水平 / 橫向擴展指的就是,增加計算機數量。
  10. 衡量系統可擴展性的常見指標是加速比(Speedup),也就是一個系統進行擴展後相對擴展前的性能提升。

03 | 分佈式互斥:有你沒我,有我沒你

  1. 霸道總裁:集中式算法
    在這裏插入圖片描述
  • 協調者會成爲系統的性能瓶頸。
  • 容易引發單點故障問題。
  1. 民主協商:分佈式算法
    在這裏插入圖片描述
    在這裏插入圖片描述
    如上所示,每個程序都會自己維護一個隊列,只需發送請求和答覆請求功能即可。
    在分佈式領域中,我們稱之爲分佈式算法,或者使用組播和邏輯時鐘的算法。
    缺點:
  • 問題1:可用性很低,在大型系統中使用分佈式算法,消息數量會隨着需要訪問臨界資源的程序數量呈指數級增加,容易導致高昂的“溝通成本”。
  • 問題2:一旦某一程序發生故障,無法發送同意消息,那麼其他程序均處在等待回覆的狀態中,使得整個系統處於停滯狀態,導致整個系統不可用。
    針對問題2的改進:如果檢測到一個程序故障,則直接忽略這個程序,無需再等待它的同意消息。但這樣就引來更大的複雜度。
    使用場景:適用於臨界資源使用頻度較低,且系統規模較小的場景。在這裏插入圖片描述
  1. 輪值 CEO:令牌環算法
    所有程序構成一個環結構,令牌按照順時針(或逆時針)方向在程序之間傳遞,收到令牌的程序有權訪問臨界資源,訪問完成後將令牌傳送到下一個程序;若該程序不需要訪問臨界資源,則直接把令牌傳送給下一個程序。
    在這裏插入圖片描述
    單點故障時,將令牌傳送給故障點的下個節點,這樣就需要每個節點知道所有節點。
    缺點:不需要訪問資源的程序,也需要接收並傳遞令牌,會帶來一些無效通信。

  2. 以上三種算法都只適用於規模小、節點數少的系統。可進一步瞭解:兩層結構的分佈式令牌環算法。
    在這裏插入圖片描述

04 | 分佈式選舉:國不可一日無君

  1. 主節點的存在,就可以保證其他節點的有序運行,以及數據庫集羣中的寫入數據在每個節點上的一致性。但如果主節點故障,就會出現很大問題。
  2. 國不可一日無君,所以我們需要分佈式選舉的算法來選舉主。
  3. 目前常見的選主方法:
  • 基於序號選舉的算法:Bully 算法。
  • 多數派算法:Raft算法、ZAB算法。
  1. Bully算法(長者爲大)
    選舉原則:選取 ID 最大的節點作爲主節點。
    Bully 算法在選舉過程中,需要用到以下 3 種消息:
  • Election 消息,用於發起選舉;
  • Alive 消息,對 Election 消息的應答;
  • Victory 消息,競選成功的主節點向其他節點發送的宣誓主權的消息。

Bully 算法選舉的原則是“長者爲大”,意味着它的假設條件是,集羣中每個節點均知道其他節點的 ID。在此前提下,其具體的選舉過程是:

  • 集羣中每個節點判斷自己的 ID 是否爲當前活着的節點中 ID 最大的,如果是,則直接向其他節點發送 Victory 消息,宣誓自己的主權;
  • 如果自己不是當前活着的節點中 ID 最大的,則向比自己 ID 大的所有節點發送 Election 消息,並等待其他節點的回覆;
  • 若在給定的時間範圍內,本節點沒有收到其他節點回復的 Alive 消息,則認爲自己成爲主節點,並向其他節點發送 Victory 消息,宣誓自己成爲主節點;若接收到來自比自己 ID 大的節點的 Alive 消息,則等待其他節點發送 Victory 消息;
  • 若本節點收到比自己 ID 小的節點發送的 Election 消息,則回覆一個 Alive 消息,告知其他節點,我比你大,重新選舉。
    在這裏插入圖片描述
    優點:選舉速度快、算法複雜度低、簡單易實現。
    缺點:需要每個節點有全局的節點信息,因此額外信息存儲較多;其次,任意一個比當前主節點 ID 大的新節點或節點故障後恢復加入集羣的時候,都可能會觸發重新選舉,成爲新的主節點,如果該節點頻繁退出、加入集羣,就會導致頻繁切主。
  1. Raft 算法(民主選舉)
    選舉原則:少數服從多數
    採用 Raft 算法選舉,集羣節點的角色有 3 種:
  • Leader,即主節點,同一時刻只有一個 Leader,負責協調和管理其他節點;
  • Candidate,即候選者,每一個節點都可以成爲 Candidate,節點在該角色下纔可以被選爲新的 Leader;
  • Follower,Leader 的跟隨者,不可以發起選舉。

Raft 選舉的流程,可以分爲以下幾步:

  • 初始化時,所有節點均爲 Follower 狀態。
  • 開始選主時,所有節點的狀態由 Follower 轉化爲 Candidate,並向其他節點發送選舉請求。
  • 其他節點根據接收到的選舉請求的先後順序,回覆是否同意成爲主。這裏需要注意的是,在每一輪選舉中,一個節點只能投出一張票。
  • 若發起選舉請求的節點獲得超過一半的投票,則成爲主節點,其狀態轉化爲 Leader,其他節點的狀態則由 Candidate 降爲 Follower。Leader 節點與 Follower 節點之間會定期發送心跳包,以檢測主節點是否活着。
  • 當 Leader 節點的任期到了,即發現其他服務器開始下一輪選主週期時,Leader 節點的狀態由 Leader 降級爲 Follower,進入新一輪選主。
    節點狀態遷移圖
    優點:選舉速度快、算法複雜度低、易於實現。
    缺點:系統內每個節點都可以相互通信,且需要獲得過半的投票數才能選主成功,因此通信量大。但不會出現Bully算法那樣的新節點加入頻繁切主的情況。
  1. ZAB算法(具有優先級的民主投票)
    相較於 Raft 算法的投票機制,ZAB 算法增加了通過節點 ID 和數據 ID 作爲參考進行選主,節點 ID 和數據 ID 越大,表示數據越新,優先成爲主。
    使用 ZAB 算法選舉時,集羣中每個節點擁有 3 種角色:
  • Leader,主節點;
  • Follower,跟隨者節點;
  • Observer,觀察者,無投票權。
    選舉過程中,集羣中的節點擁有 4 個狀態:
  • Looking 狀態,即選舉狀態。當節點處於該狀態時,它會認爲當前集羣中沒有 Leader,因此自己進入選舉狀態。
  • Leading 狀態,即領導者狀態,表示已經選出主,且當前節點爲 Leader。
  • Following 狀態,即跟隨者狀態,集羣中已經選出主後,其他非主節點狀態更新爲 Following,表示對 Leader 的追隨。
  • Observing 狀態,即觀察者狀態,表示當前節點爲 Observer,持觀望態度,沒有投票權和選舉權。

投票過程中,每個節點都有一個唯一的三元組 (server_id, server_zxID, epoch),其中 server_id 表示本節點的唯一 ID;server_zxID 表示本節點存放的數據 ID,數據 ID 越大表示數據越新,選舉權重越大;epoch 表示當前選取輪數,一般用邏輯時鐘表示。
選舉過程中通過 (vote_id, vote_zxID) 來表明投票給哪個節點,其中 vote_id 表示被投票節點的 ID,vote_zxID 表示被投票節點的服務器 zxID。ZAB 算法選主的原則是:server_zxID 最大者成爲 Leader;若 server_zxID 相同,則 server_id 最大者成爲 Leader。
優點:穩定性比較好。
缺點:容易出現廣播風暴。除了投票,還增加了對比節點 ID 和數據 ID,這就意味着還需要知道所有節點的 ID 和數據 ID,所以選舉時間相對較長。

在這裏插入圖片描述
7. 多數派選主算法通常採用奇數節點。
在這裏插入圖片描述

05 | 分佈式共識:存異求同

  1. 事務,其實是包含一系列操作的、一個有邊界的工作序列,有明確的開始和結束標誌,且要麼被完全執行,要麼完全失敗,即 all or nothing。通常情況下,我們所說的事務指的都是本地事務,也就是在單機上的事務。
  2. 分佈式事務,就是在分佈式系統中運行的事務,由多個本地事務組合而成。
  3. ACID具體含義:
  • 原子性(Atomicity),即事務最終的狀態只有兩種,全部執行成功和全部不執行。
  • 一致性(Consistency),是指事務操作前和操作後,數據的完整性保持一致或滿足完整性約束。
  • 隔離性(Isolation),是指當系統內有多個事務併發執行時,多個事務不會相互干擾。
  • 持久性(Durability),也被稱爲永久性,是指一個事務完成了,那麼它對數據庫所做的更新就被永久保存下來了。
  1. 強一致性 VS BASE理論
  2. 實現分佈式事務有以下 3 種基本方法:
  • 基於 XA 協議的二階段提交協議方法(強一致性)
  • 三階段提交協議方法(強一致性)
  • 基於消息的最終一致性方法(BASE理論)
  1. 基於 XA 協議的二階段提交方法
    XA 協議可以分爲兩部分,即事務管理器和本地資源管理器。
    事務管理器作爲協調者,負責各個本地資源的提交和回滾;而資源管理器就是分佈式事務的參與者,通常由數據庫實現,比如 Oracle、DB2 等商業數據庫都實現了 XA 接口。
    二階段提交協議(The two-phase commit protocol,2PC),用於保證分佈式系統中事務提交時的數據一致性。
    XA 在全局事務中用於協調多個資源的機制。
    兩階段提交協議的執行過程,分爲
    投票(voting):
    在這裏插入圖片描述
    提交(commit):
    在這裏插入圖片描述
    缺點:
  • 同步阻塞問題:二階段提交算法在執行過程中,所有參與節點都是事務阻塞型的。也就是說,當本地資源管理器佔有臨界資源時,其他資源管理器如果要訪問同一臨界資源,會處於阻塞狀態。
  • 單點故障問題:基於 XA 的二階段提交算法類似於集中式算法,一旦事務管理器發生故障,整個系統都處於停滯狀態。
  • 數據不一致問題:在提交階段,當協調者向參與者發送 DoCommit 請求之後,如果發生了局部網絡異常,或者在發送提交請求的過程中協調者發生了故障,就會導致只有一部分參與者接收到了提交請求並執行提交操作,但其他未接到提交請求的那部分參與者則無法執行事務提交。
  1. 三階段提交方法(Three-phase commit protocol,3PC)
    爲了解決兩階段提交的同步阻塞和數據不一致問題,三階段提交引入了超時機制和準備階段。
    超時機制:如果協調者或參與者在規定的時間內沒有接收到來自其他節點的響應,就會根據當前的狀態選擇提交或者終止整個事務。
    準備階段:在第一階段和第二階段中間引入了一個準備階段,也就是在提交階段之前,加入了一個預提交階段。在預提交階段排除一些不一致的情況,保證在最後提交之前各參與節點的狀態是一致的。
    3PC 把 2PC 的提交階段一分爲二,這樣三階段提交協議就有 CanCommit、PreCommit、DoCommit 三個階段。
  • CanCommit 階段
    在這裏插入圖片描述
  • PreCommit 階段
    在這裏插入圖片描述
  • DoCommit 階段
    在這裏插入圖片描述
    在 DoCommit 階段,當參與者向協調者發送 Ack 消息後,如果長時間沒有得到協調者的響應,在默認情況下,參與者會自動將超時的事務進行提交,不會像兩階段提交那樣被阻塞住。
  1. 基於分佈式消息的最終一致性方案
    2PC 和 3PC 這兩種方法,有兩個共同的缺點,一是都需要鎖定資源,降低系統性能;二是,沒有解決數據不一致的問題。
    基於分佈式消息的最終一致性方案的事務處理,引入了一個消息中間件(Message Queue,MQ),用於在多個應用之間進行消息傳遞。
    在這裏插入圖片描述
    購物流程:
    在這裏插入圖片描述
  2. 三種方法對比
    在這裏插入圖片描述
  3. 剛性事務與柔性事務
    剛性事務,遵循 ACID 原則,具有強一致性。比如,數據庫事務。
    柔性事務,其實就是根據不同的業務場景使用不同的方法實現最終一致性,也就是說我們可以根據業務的特性做部分取捨,容忍一定時間內的數據不一致。柔性事務的最終一致性,遵循的是 BASE 理論。
  4. BASE 理論
    BASE 理論包括:
    基本可用(Basically Available):分佈式系統出現故障的時候,允許損失一部分功能的可用性。
    柔性狀態(Soft State):在柔性事務中,允許系統存在中間狀態,且這個中間狀態不會影響系統整體可用性。
    最終一致性(Eventual Consistency):事務在操作過程中可能會由於同步延遲等問題導致不一致,但最終狀態下,數據都是一致的。
    在這裏插入圖片描述

07 | 分佈式鎖:關鍵重地,非請勿入

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章