天天看點

分布式系統架構技術分析(一)

原創聲明:本文系作者原創,謝絕個人、媒體、公衆号或網站未經授權轉載,違者追究其法律責任。

在 20 世紀 60 年代,大型主機憑借其超強的計算和 IO 處理能力以及在穩定性和安全性方面的卓越表現,在很長的一段時間裡引領了計算機行業的發展。随着大型主機的發展,集中式的計算機系統架構也成為了主流。随着計算需求的增長和計算場景的多樣化,集中式的處理模式越來越顯得捉襟見肘,同時随着 PC 技術的成熟和普及,PC 機也進入各行各業,成為更容易擷取的計算資源,但随之也産生了大量閑散的計算單元,網格計算的概念被随之提出,并随着計算機網絡化和微型化的發展趨勢,不斷演進發展。整個分布式計算的理論和實踐也走向成熟,計算機系統也開始從集中式向分布式架構的演進。

在前一篇《集中式架構與分布式架構比較》中,我們已經對兩種風格的架構進行了詳細對比,顯然分布式架構具有明顯的優勢,在此不再贅述。本專題中将聚焦分析分布式架構的幾個關鍵方面,在本文我們将探讨分布式架構的主要組成要素及其運作機制。

分布式系統的主要特征

分布式系統是其元件分布在連網的計算機上,元件之間通過傳遞消息進行通信和動作協調的系統。一個标準的分布式系統在沒有任何特定業務邏輯限制的情況下,一般有以下幾個特征:

分布性:一個分布式系統中的計算機在空間部署上是可以随意分布的,這些計算機可能處于不同的機櫃上,不同的城市的機房中,或者是世界上任何一個角落。同時,機器的分布情況也會随時變動;

并發性:在一個計算機網絡中,程式運作過程中的并發性操作是非常常見的行為,例如同一個分布式系統的多個節點,可能會并發地操作一些共享的資源,諸如資料庫或分布式存儲等,如何準确并高效地協調分布式并發操作也成為了分布式系統架構與設計中最大的挑戰之一;

缺乏全局時鐘:分布式系統中多個程序可能在空間上分布式在各處,程序之間通過交換消息來互相協作,密切的協作通常取決于對程式動作發生的時間的共識。但在分布式系統中,各程序與時鐘同步所達到的準确性是有限的,即沒有一個正确時間的全局概念;

故障獨立性:組成分布式系統的所有計算機,都有可能發生任何形式的故障。單個子產品的故障相對容易預知并設計應對邏輯,但分布式系統可能以新的方式出現故障。網絡故障導緻互連的計算機的隔離,但它們并不一定會停止運作,而且程式很難判斷是網絡故障還是因為延遲。同樣,當被網絡隔離計算程式在異常終止時,也許不能馬上通知與它通信的其他元件了解。系統的每個元件會單獨地出現故障,而其他元件還在運作。

分布式系統能夠實作高可用、高吞吐、大容量存儲、海量計算、并行計算等優異能力,天然的分布性和可伸縮等特性,也打破了實體上單機的瓶頸,使其能不斷支撐着業務的發展而演進,并推進了雲計算、大資料、人工智能等領域的發展。但是正如每個硬币都有兩面,分布式系統的複雜性,也使其在設計、研發、運作、維護、安全性等方面都面臨更多的挑戰。

主要組成要素及其運作機制

分布式服務

分布式系統下節點間服務通訊有兩種途徑,一種是通過 RPC(Remote Procedure Call) 實作兩點間通訊,可以設計成同步通訊,也可以是異步的;一種是通過消息中間件實作通信,一般是異步通訊方式。

RPC 調用

RPC 調用也是分布式環境下常見的通訊方式,有同步的模式,也有異步的模式。同步模式下,用戶端發起調用并阻塞目前線程,直到服務端處理完畢傳回響應才完成整個調用過程;異步模式下,用戶端發起調用後立即傳回,并記錄目前請求,直到接收到服務端響應後才找到對應的請求進行結果的處理,并完成整個調用過程。

RPC 調用中一般隻有兩個角色:用戶端和服務端,但在分布式環境下服務端可能有多台機器,他們共同組成一個叢集,每台都提供一樣的服務。這時就要有一種機制能讓用戶端将持續不斷的請求均衡的分發到所有的服務端,一般将這種機制稱為「負載均衡」。負載均衡可以在用戶端實作,也可以通過專門的負載均衡裝置實作。如果采用用戶端負載均衡方案,需要讓用戶端感覺所有服務端的機器位址和端口,需要引入一套「服務發現和內建的體系」,好處是通訊是點對點的,比較高效,且不存在單點。如果使用專門負載均衡裝置,則用戶端隻需感覺負載均衡裝置的位址,由它來對接所有服務端,并均衡服務請求,這種模式比較簡單,但存在性能單點,且延長了請求鍊路,穩定性也會受影響。無論是用戶端還是專門裝置做負載聚合,都可以根據不同的場景采用适合的負載均衡政策,常見的政策有随機(Random)、輪詢(RoundRobin)、最快連接配接數(Fastest Connection)、最小連接配接數(Least Connection)等等。

消息中間件

消息中間件一般是獨立部署的一組應用程式,負責消息的接收和投遞。整個通訊過程是異步的,有消息釋出者、消息中間件和消息訂閱者三個角色,消息從釋出端發出後,會被消息中間件接收并做持久化,消息的消費有兩種常見的模式,一種是消息中心主動投遞的模式(推模式),一種是訂閱者主動拉取的模式(拉模式)。在推模式下,釋出者釋出消息,消息發到消息中心做持久化,然後被投遞到訂閱端叢集,一般來說會選擇在所有訂閱者中随機選一台投遞,在這種模式下,要求消息訂閱者叢集的消息消費速度要能跟上釋出消息是速度;在拉模式下,消費者根據隊列裡消息總數來做均分,主動連上消息中間件進行消費,對消費速度沒有速度限制,是以一般拉模式的消息中間件會提供更強的消息扛積壓能力。

由于消息被持久化,是以可以做到消息的可靠投遞,保證了分布式環境下通訊的可靠達到。在分布式環境下,一個系統可能會在一次事務操作中通過消息的方式去改變其它系統的狀态(主要指存儲的狀态),為了能模拟類似事務的一緻性,異步消息可以利用 DB 的持久化來支援事務型消息。事務型消息指的是釋出消息的應用系統在本地資料庫事務操作序列中發送的消息。此類消息的投遞與資料庫事務狀态保持一緻,當事務狀态是送出時,消息會被投遞到訂閱者,當事務狀态是復原時,消息不會被投遞到訂閱者,這也是分布式環境下消息中間件需要支援的特殊場景。

分布式資料存儲

分布式緩存

當傳統資料庫面臨大規模資料通路時,磁盤 I/O 能力往往成為性能瓶頸,進而導緻過高的響應延遲,而比較常用的提升性能的手段,是在應用和資料庫之間加入一層分布式緩存來提升資料通路性能,分布式緩存将高速記憶體作為資料對象的存儲媒體,理想情況下可以獲得記憶體級的讀寫性能,常見的緩存實作會通過 LRU 算法來緩存通路最多的資料,進而提升緩存效率。

通過分布式緩存伺服器叢集,将緩存資料分布到叢集多台伺服器上可在一定程度上改善緩存的可用性,同時也能起到擴充緩存容量的作用,當一台緩存伺服器當機的時候,隻有部分緩存資料丢失,重新從資料庫加載這部分資料不會對資料庫産生很大影響。

分布式緩存還具有支援彈性擴充的能力,通過動态增加或減少節點,應對變化的資料通路負載,提供可預測的性能與擴充性,同時也能最大限度地提高資源使用率

分布式緩存比較典型應用場景包括:

應用對象緩存:緩存系統作為 ORM 架構的二級緩存對外提供服務,目的是減輕資料庫的負載壓力,加速應用通路;

狀态緩存:緩存包括 Session 會話狀态及應用橫向擴充時的狀态資料等,這類資料一般是難以恢複的,對可用性要求較高,多應用于高用叢集;

并行處理:通常涉及大量中間計算結果需要共享;

事件處理:分布式緩存提供了針對事件流的連續查詢 (continuous query) 處理技術,滿足實時性需求;

極限事務處理:分布式緩存為事務型應用提供高吞吐率、低延時的解決方案,支援高并發事務請求處理,多應用于鐵路、金融服務和電等領域。

通過配置合理容量的分布式緩存,能在提升應用資料通路性能的同時,降低總體擁有成本,是以架構設計上做到合理利用緩存,變得就越來越重要。

分布式檔案系統

分布式檔案系統,是指允許檔案通過網絡在多台計算機中分散存儲的共享檔案系統,它通過網絡将分布在不同區域的多台計算機連接配接在一起進而組合成容量更大,處理能力更強的分布式檔案存儲系統。分布式檔案系統很好的解決單台計算機存儲和處理能力存在上限的問題,具備大的存儲容量和處理能力的擴充能力。

在分布式檔案系統中,用戶端并非直接通路底層存儲,而是通過網絡以特定的通信協定和伺服器溝通,進而完成檔案存儲操作,借由通信協定的設計,可以讓用戶端和伺服器端都能根據通路控制清單或是授權,來限制對于檔案系統的通路。由于分布式檔案系統的網絡接入特性,使得不同使用者都能通過網絡接入分布式檔案系統,實作檔案資料的共享,從使用者角度看,分布式檔案系統與單機檔案系統看到的視圖是一樣的,使用方式也相同。

分布式檔案系統除了能提供比單機檔案系統更大的存儲容量和處理能力外,通過資料複制與容錯,也擁有了本地檔案系統所無法具備的資料備份、資料安全等優點,也就是說,即使系統中有一小部分的節點脫機,整體來說系統仍然可以持續運作而不會有資料損失。

分布式資料庫

随着資料量的高速增長,分布式資料庫技術也得到了快速的發展,傳統的關系型資料庫開始從集中式模型向分布式架構發展。分布式資料庫是指利用高速計算機網絡将實體上分散的多個資料存儲單元連接配接起來組成一個邏輯上統一的資料庫。分布式資料庫的基本思想是将原來集中式資料庫中的資料分散存儲到多個通過網絡連接配接的資料存儲節點上,以擷取更大的存儲容量和更高的并發通路量。

分布式資料庫可以按需增加、減少資料庫處理節點,很好地解決了單台資料庫的存儲和處理能力上限問題;除此之外,分布式資料庫往往具備較強的容錯能力,通過資料複制、副本備援,當某個處理節點出現故障時,能夠自動恢複,對使用者沒有感覺。最後,分布式資料庫底層采用廉價伺服器,相比傳統單機資料庫使用的高端伺服器和高端存儲,成本大幅度降低。

在分布式資料庫中,用戶端并非直接通路底層的存儲系統,而是使用結構化查詢語言(SQL語言)通路資料庫節點,再由資料庫節點的 SQL 引擎翻譯成針對底層存儲系統的操作。一套分布式資料庫往往會服務多個業務,分布式資料庫内部支援多個業務之間的隔離,當某個業務出現異常時,隻會影響該業務,不會對其它業務造成影響。螞蟻的 OceanBase 是一個典型的分布式資料庫。使用分布式資料庫,将大大降低單庫故障的發生機率,并簡化單庫故障的恢複機制。再結合分布式資料中間件在業務次元資料分片和路由、資料源動态調整、應用層高可用容災、異構資料源适配等能力,将能很好的實作分布式環境下 DB 的高性能通路和高可用。

分布式資料中間件

關系型資料庫是經典的持久化解決方案,但在海量業務場景下也會遇到單表的容量瓶頸和單庫的性能瓶頸。按照分布式的思想,資料也要拆分,讓集中在單點的讀寫通路分布到多個 DB 伺服器上,進而獲得容量和性能上的彈性延伸能力。根據業務場景可分為垂直拆分(按業務)、水準拆分(按請求/使用者做哈希,或者做區間拆分)、讀寫拆分等。

按照垂直拆分後的資料會造成本來單庫事務變成跨庫事務,很難通過傳統資料庫的機制來保證 ACID,需要引入一種應用層的,基于服務的事務協調機制。這個下文會有專門闡述。按照水準拆分的資料,需要按照某些業務次元将資料拆分到不同的庫表,進而解決資料水準擴充的問題,也提升了整體的 QPS,使資料層具備 TB+/天 的吞吐能力。資料拆分後,每次資料通路需要按照分庫分表的規則進行路由,本質上是通過規則對原始 SQL 進行重寫,拆分成多條 SQL,并分發給連結多個庫的資料源去執行,并彙總結果。由于整個過程都在應用層進行,為屏蔽複雜性,需要将上述邏輯封裝一層中間件類庫中,并通過标準 JDBC 接口對外暴露接口,讓業務透明的完成整個資料庫的通路過程。

通過一層統一的分布式資料中間件,讓業務通過标準 SQL 和标準 JDBC 接口就能通路一組理論容量「無限大」的關系型資料庫叢集,并且具有很好的性能。同時,通過這層中間件,也能實作所有資料庫參數的動态調整、路由規則動态調整、資料庫分片權重的調整,進而在應用層實作資料庫通路的高可用,且不依賴于資料庫高可用機制,甚至提供更靈活強大的故障容忍能力。此外,标準 SQL 和 JDBC 屏蔽了底層資料庫的實作,使應用具備透明對接異構資料源的能力,實作複雜場景的業務通路和一些雙寫雙讀的需求。

分布式事務

傳統關系型資料庫的事務模型必須遵守 ACID 原則。在單資料庫模式下,ACID 模型能有效保障資料的完整性,但是在大規模分布式環境下,單庫無法承載高并發和海量資料,是以資料會被通過垂直拆分或水準拆分到不同的 DB 中,一個業務往往會跨越多個資料庫。在 JavaEE 規範中使用 2PC (2 Phase Commit, 兩階段送出) 來處理跨 DB 環境下的事務問題,但是 2PC 是反可伸縮模式,也就是說,在事務處理過程中,參與者需要一直持有資源直到整個分布式事務結束。這樣,當業務規模達到千萬級以上時,2PC 的局限性就越來越明顯,系統可伸縮性會變得很差。基于 BASE 的思想可以仿照 2PC 的方式,在應用層來實作分布式環境下多個事務協調一緻。 在充分保障分布式環境下高可用性、高可靠性的同時兼顧資料一緻性的要求,其最大的特點是保證資料最終一緻 (Eventually consistent)。

在分布式事務中,可以簡單分成事務發起方和事務參與者兩個角色。發起方負責啟動分布式事務,觸發建立主事務記錄。發起方是分布式事務的總體協調者,負責調用參與者的服務,記錄相應的事務日志,并感覺整個分布式事務狀态來決定整個事務是 COMMIT 還是 ROLLBACK。參與者是分布式事務中的一個原子機關,所有參與者都必須定義 prepare、commit、rollback 3個基本接口,并保證其業務資料的幂等性,也必須保證 prepare 中的資料操作能夠被送出 (COMMIT) 或者復原 (ROLLBACK)。

整個協調過程從發起方開啟一個本地事務開始,過程中參與者會顯式調用參與方的業務方法,這些顯式調用的方法即為一階段的 prepare 方法,一般參與方會在該方法内鎖定資源。這些方法調用可以采用第一小節提到的「消息中間件」,也可以采用「RPC 通訊」。一旦這次本地事務成功,則本地事務送出,發起方會調用第二階段的真正 commit 方法,來讓所有參與方的事務完成第二階段的送出。本地事務送出失敗或者在這之前某個邏輯中失敗(可能是本地邏輯異常,也可能參與方一階段失敗),則本地事務失敗,發起方會負責完成一階段的所有復原操作,避免出現不一緻情況。

在分布式環境下,單點故障是個常态,是以無論是發起方還是參與方都可能在任何一刻不可用,此時需要一個第三方的恢複系統來感覺所有的事務狀态,并通過定期輪詢來發現異常狀态的事務記錄,并将其恢複至最終一緻。分布式事務的詳細介紹可以參考《分布式事務綜述》

在下一篇《分布式系統架構技術分析(二)》中,将從分布式系統架構的容量規劃和容災管控兩個方面進行分析,幫助讀者更好的了解分布式系統架構。