天天看點

分布式架構設計概要總結

分布式架構概要總結

建構分布式的原因

業務架構的演進
分布式架構設計概要總結

在上圖簡單以時間線為準,粗略描述了我們系統架構随着業務的需求考量以及業務的發展,系統承擔的并發量也将逐漸提升,這就要求我們的系統架構需要開始思考如何利用現有的資源來解決。

我們目前急需處理并發請求的服務.而思考的方向可以從我們已有的計算機知識體系中找到答案。比如:

  • 對于并發問題,我們知道處理共享資源可以通過加鎖的方式來保證我們的線程安全,那麼在有限的資源下又要如何提升我們的并發量,于是我們很容易想到hashmap是如何處理線程安全的,對此我們就會考慮到一個設計思想,那就是分而治之的政策,即是否可以将共享資源拆分成多份來緩解我們的壓力,即叢集.
  • 這個時候我們的流量壓力通過叢集分擔到各個應用中,但是此時對資料庫的壓力反而增加了,于是我們會想到使用緩存政策來緩解我們的壓力,對于緩存架構,我們也可以采用CPU高速緩存的政策來對我們現有的服務進行改進。
  • 另外,随着業務的增長以及需求不斷地調整變化,有時候為了提升我們的查詢性能,還需要以不同的次元重新建構資料庫表結構。比如訂單服務,可以以使用者維護進行資料異構産生使用者與訂單服務的資料庫表結構來提升我們的查詢性能。其實對于這種資料異構在程式設計設計中也是有展現的,比如表單的業務 bean 與資料庫存儲的業務 bean 多少存在一些備援但可能是類型或者是狀态顯示不同,目的當然是簡化便于了解。
  • 随着業務不斷擴大,團隊人員也在增加,考慮到快速傳遞産品需求,我們可以劃分團隊負責不同的業務線,于是便有了服務的垂直拆分,也就是我們的服務化架構,在分布式架構設計中引入服務化架構是我們根據團隊以及業務進行拆分的結果,目的是為了更快速傳遞,同時也是為了更為專注業務開發的落地實作。

引入性能技術的優化方案之後,這個時候我們從另外一個視角來看,即一個置身于網際網路大環境下的項目系統,我們需要保證分布式系統服務的高可用。

建構分布式系統的兩個核心因素

對此,一個分布式系統服務需要具備以下兩個因素:

  • 增大系統容量: 我們的業務量越來越大,而要能應對越來越大的業務量,采取分而治之的設計思想,通過進行水準或是垂直拆分業務系統,讓其變成一個分布式的架構。
  • 保證系統服務的高可用: 為了增大系統容量,我們将業務進行拆分,彼此獨立,但是每一塊業務線都有其重要意義。是以我們就需要保證每一塊業務線的服務不能存在單點故障,這樣整個系統不會因為單點服務出故障而導緻業務服務系統不可用,是以需要通過做節點備援系統以消除單點故障,進而提高系統的可用性。
小結

我們使用分布式的設計來源于"分而治之"的思想,從整個系統架構上看,建構分布式架構的原因就是要扛住網際網路海量并發請求處理以及在此基礎上保證我們的系統服務具備高可用,抑或是允許一小部分服務不可用。

分布式術語

節點

可以是作業系統上的一個程序服務,也可以是分布式系統中一組提供處理邏輯的程式并能夠獨立部署運作,在整個分布式系統中與其他服務協作也可以獨立完成業務的請求處理操作。

叢集

在分布式系統中,為了提升服務的并發處理能力,部署多個節點來提供相同的一組業務服務操作,這多個提供服務的節點組成一個叢集。

副本

在分布式系統中提供資料抑或是服務的備援來保證系統的高可用,資料副本是指在不同的節點上持久化存儲一份相同的資料,服務副本是指在不同的節點上部署一套或一組提供相同業務處理邏輯的服務,一般形成主從來保證服務節點的高可用。

中間件

獨立于應用服務,位于作業系統之上的一套為叢集節點服務解決問題的通用方案的元件,簡化開發人員的工作,讓開發者更專注于業務上的開發。

比如服務與服務之間通過消息中間件實作異步通信,實作服務解耦;

為了加速資料通路速度,我們引入緩存中間件,為應用層與存儲層提供一個緩存的過程,避免所有相同的資料查詢操作的流量都落地到資料存儲層;

同時我們還看到接入層節點抑或是網關服務節點要實作高可用保證,需要引入負載均衡中間件實作高可用;

再或者應用層與實作分片的資料存儲層進行資料互動,為簡化開發以及查詢比對等因素引入資料庫中間件,進而對于應用層仍然可以透明地實作對資料存儲的CRUD等操作,而無須關系資料比對以及一緻性等問題。

SOA與微服務架構

SOA為面向服務的架構,是屬于一種設計方法,每個服務之間都互相獨立且通過網絡進行服務調用來完成一次複雜的業務請求操作;

微服務架構是在SOA的基礎上演進而來,強調元件化與服務化,每個元件提供獨立的服務可以實作可伸縮性的擴充。可以獨立開發,設計,部署與優化而不影響微服務中其他的元件。

分布式協調

其一分布式的多個服務節點之間的業務處理邏輯仍然需要保證與單體架構執行的業務邏輯處理順序一緻,即保證服務節點處理業務請的邏輯具備有序性;

其二是對于共享資源的争用,在單體架構中我們通過加鎖的方式來保證并發處理共享資源的安全性,同理對于分布式的多服務節點對共享資源進行事務操作的時候我們也需要協調各個服務節點的并發控制,保證系統服務中的共享資源的事務操作具備原子性以及資料一緻性。

是以,對于分布式協調我們可以了解一個是協調服務節點來保證業務處理的有序性,一個是協調服務節點來保證并發操作共享資源的原子性以及資料的一緻性。

服務治理

對于服務治理的了解,我們需要切換一個次元,此時應該從分布式服務化的架構設計上來看待問題,那麼服務與服務之間的通信流程如下:

服務啟動并注冊到注冊中心 - 調用方從注冊中心擷取被調用方的服務清單 - 調用方通過負責均衡的方式選擇服務 - 調用選擇的服務,此時通過網絡傳輸的方式傳遞消息 - 被調用方接收到消息并執行調用傳回,

這裡涉及到業務拆分成獨立服務,服務注冊,服務發現,服務依賴以及服務調用鍊等關系,服務治理就是需要将服務之間的依賴與調用鍊全部梳理出來統一存儲和管理,這樣子我們就能夠針對各個服務進行分析與優化等操作。

DevOps&自動化運維

利用CI/CD等持續內建工具來完成一系列業務服務的釋出流程,即代碼review後送出 - 測試-單元測試-打包-內建測試-UI測試-測試環境釋出部署服務-預生産灰階釋出服務-真是釋出部署服務等一系列流程可以稱為DevOps全流程,這對于我們做服務化架構能夠實作快速疊代開發;

有了DevOps之後,我們就可以針對我們的業務服務進行自動伸縮,故障轉移,配置管理,狀态管理等一系列自動化運維工作。

分布式技術

架構的高性能
分布式架構設計概要總結

這裡引入網名左耳朵耗子講解分布式高性能相關的技術,我覺得已經很好地诠釋了分布式高性能技術棧,對于高性能方面,自己也基于上述的基礎上做一些補充:

叢集與負載均衡

通過水準擴充業務處理能力來提升系統的并發處理能力。

緩存設計

在我們的上述服務進行水準抑或是垂直擴充的時候,這個時候我們的業務吞吐量也會增加,這個時候會把所有的流量壓力打到資料存儲系統上,為了緩解資料存儲系統的壓力,這個時候我們會考慮将資料進行冷熱劃分,對于熱點資料集中在緩存系統服務以降低我們的資料存儲壓力。

對于緩存的設計存在以下三種模式:

  • 其一是Cache Aside更新模式,即失效 - 命中 - 更新政策;
  • 其二是Read/Write Through更新模式,即緩存更新對應用程式透明,對于應用程式而言隻有一個資料存儲操作,由cache負載更新資料操作;
  • 其三是Write Back模型,類似于Linux下的Page Cache算法,應用程式直接将資料更新到cache中,有cache異步批量更新到資料庫中。
垂直拆分業務(服務化設計)

當我們的一個服務節點承擔複雜繁多的業務服務的時候,必然會影響到我們業務處理的能力,為了提升我們的并發處理能力,為了提升我們的系統并發能力,可以考慮将我們的業務進行垂直拆分,于是就有了一個請求的處理需要多個服務之間進行協作完成。

資料鏡像與分區(讀寫分離/分庫分表)

盡管使用緩存可以緩解我們的服務壓力,但是仍然無法從根源上緩解流量對資料存儲的壓力,于是我們一方面會做讀寫分離,做主從叢集,主節點負責處理事務的資料寫入,從節點資料負責資料的讀取;

另一方面為了提升單庫單表的并發能力,這個時候我們也是借助分而治之的設計思想,采取分庫分表的思路來緩解我們單庫單表的流量壓力。

借助MQ中間件實作異步處理

可以通過中間件技術實作異步處理,對流量進行削峰緩沖,進一步提高了程式的并發處理能力以及系統的穩定性。

資料異構設計

将同一個業務資料按照業務需求的用途劃分為不同的資料倉庫存儲以适用相應的業務需求場景,

比如對于爬蟲的聚合資訊資料來源存在很多不确定的因素,我們可以通過MQ的方式接收資料變更并将資料持久化存儲到ES存儲的引擎中;

抑或是查詢一個使用者的訂單資訊,如果按照訂單表的訂單ID進行拆分,則需要聚合多張表才能傳回相應的聚合資料,這個時候可以采取按照使用者次元來進行異構一個與使用者相關的訂單資料倉庫的政策(存在資料備援,但是提升讀取性能)。

高可用設計
分布式架構設計概要總結

同樣地,這裡也是引入網名左耳朵耗子講解分布式高可用相關的技術,在此基礎自己也做以下的一些補充:

服務備援與負載均衡技術

從叢集角度上思考,我們需要考慮叢集是流量如何分擔到叢集服務的節點,叢集服務節點出現異常或者不可用的時候流量如何切換,這個時候我們就需要考慮到負載均衡技術來幫助我們實作流量分發的排程,對服務節點采取心跳檢測以及當服務節點異常采取重試與流量切換重新排程配置設定可用服務節點來避免單點故障問題,簡而言之服務的高可用可以是服務備援與負載均衡技術來避免單點故障,實作故障自動的恢複。

隔離技術

為了防止故障蔓延到其他服務節點,我們通常會采取隔離技術來隔離拆分的業務服務,每個業務服務分别各自獨立部署,在分布式系統設計中,一般會服務的種類或者是使用者來進行隔離。

降級與限流技術

當系統承擔的并發流量服務壓力十分龐大的時候,這個時候我們需要采取保護措施,通過降級或者限流的技術來停用部分業務服務或者是拒絕部分使用者的請求操作以確定整個系統不會被流量沖垮導緻整體不可用。

逾時重試與熔斷

在服務化架構設計中,為了防止服務産生雪崩,需要在調用服務加入逾時重試以及熔斷機制,避免将錯誤蔓延到其他服務導緻整個系統服務不可用。進而縮小部分服務。

高可用架構設計

利用服務備援來避免單點故障,比如多租戶隔離,災備多活抑或是資料副本保證一緻性,高可用不僅是的服務叢集的高可用,還有就是中間件實作高可用設計。

高可用的運維

實作devops的CI或者CD的持續內建計劃任務,能夠建構執行自動化測試,實作灰階釋出部署以及線上系統的自動化控制。

緩存的高可用

對于緩存系統也需要采用叢集高可用的方式來避免單點故障以及實作故障恢複,同時對于緩存系統要實作高可用,需要注意以下幾個問題:

  • 緩存穿透:即對于不存在的資料緩存始終都是沒有命中會直接将流量打到資料存儲層上。
  • 緩存雪崩:即在某一個時刻,所有的緩存都失效過期,這個時候流量都會打到資料存儲層,很容易引起資料存儲層的并發性能問題。
  • 緩存擊穿:即針對某一個熱點緩存在某一個時間點存在并發通路量請求并且目前時間點緩存時間已經過期需要重新整理緩存,這樣也會将流量打到資料存層上。

    是以對于緩存的高可用不僅需要避免單點故障,同時還需要具備容錯能力,比如增加布隆過濾器來控制緩存穿透,根據不同的業務場景可以采取随機時間段的緩存時間來避免同一個時間點緩存失效以及對于具備熱點的共享資源緩存操作,需要借助中間件的協調者來管理和控制我們的應用服務的操作避免緩存擊穿的産生。

切流量

面臨高并發流量的接入時,我們并無法保證所有服務節點都是可用狀态,于是需要在接入層或者服務網關做故障轉移,将流量切換到可用的服務節點上。

可復原

在分布式的服務化架構設計,我們需要對服務實施版本控制與管理,一旦新釋出的服務節點産生測試不可預知的測試,為了減少服務不可用時長抑或是服務的覆寫面,我們需要對服務進行復原到上一個穩定版本以保證線上服務可用。

業務設計
防重與幂等設計

當我們應用在機關時間内接收到相同并發的事務請求操作時,這個時候我們需要考慮事務請求操作處理不論多少次請求最終隻能處理一次,這個時候可以通過設計防重key或者是防重表來保證我們隻處理一次請求。

比如下單支付操作,由于支付管道是無法避免重複支付的,是以對于我們系統服務而言就需要根據業務場景設定防重 key 來保證訂單服務抑或是将支付記錄在資料表并通過資料表進行查詢驗證,如果并發量很大的話,我們可以考慮通過MQ來接收支付管道回調的響應結果并通過鑒權驗證之後送出到MQ,再由MQ分發給消費者,這個時候就需要保證幂等,防止重複消息的消費。

事務補償機制

在分布式架構設計中,基于ACID以及BASE理論知識,事務補償操作可以是保證一系列的業務操作具備原子性而最終達到業務資料一緻性的目标,當其中某一個操作出現異常的時候,我們采取重試讓其運作得到我們期望的事件狀态,如果重試不成功,則采取人工幹預抑或是丢棄復原事件。

比如一個支付場景,使用者下單之後并沒有立即支付,此時商品扣減庫存如果在等待15min之後沒有收到使用者支付的請求,就需要将商品庫存釋放,此時就需要對此場景進行事務補償,保證我們的業務最終一緻性;

再比如一個主播提現系統,一般會有N+1或者N+7的支付平台,那麼我們進行主播打款的時候有可能由于第三方支付平台網絡不穩定導緻支付成功但是沒有傳回響應,此時我們也需要進行事務補償,針對不穩定的網絡因素進行重試與驗證處理,保證資料金額的最終一緻性.

狀态機設計

狀态機系統包含條件,事件以及事件觸發的狀态變更操作,嚴格按照一定的狀态變更規則通過外部事件觸發以及條件的判斷執行狀态變更。

比如設計一個訂單狀态的狀态機,我們需要考慮訂單狀态的變化以及對應觸發狀态變更的事件,比如下單-訂單被建立,支付-支付成功與失敗,接單-已接單狀态還是拒單狀态,訂單簽收-訂單完成以及後續的退單操作對應的訂單退款狀态等一系列事件觸發的訂單狀态變更形成一個狀态機。

背景系統可回報

可以針對一些核心業務功能采取行為記錄的日志異步化持久化到資料層上,并通過背景管理系統檢視回報以及重要核心業務流程的追蹤分析。

分布式服務名額監控
分布式架構設計概要總結

在分布式架構中,最需要做到的就是能清楚每個服務節點運作的細節,此時就需要對整個分布式系統進行全棧監控,即不論是應用服務層(業務服務化),抑或是平台元件服務還是底層機器的資源監控,我們都需要做到心中有數,才能夠針對某一個服務進行排查與優化。

  • 基礎層:主要監控底層以及資源情況,如CPU/記憶體/網絡/磁盤IO/帶寬流量等。
  • 元件層:主要監控我們引入的中間件,比如Redis/MQ等,都需要對元件的容量/io/記憶體/線程/服務節點健康狀态等名額進行監控。
  • 應用層:一般是我們的業務服務上的監控,這個時候我們更關注服務依賴,服務調用鍊,日志收集,qps/tps等因素。

分布式小結

分布式設計思考的次元
兩個目标
  • 提高系統的性能
  • 保證系統服務的高可用
宏觀的架構技術棧
  • 全棧系統監控: 單機的基礎監控 - 中間件服務監控 - 應用服務監控
  • 服務/資源排程: 計算機資源排程 - 服務資源排程 - 架構排程
  • 流量排程: 流量控制 - 流量管理 - 服務治理
  • 狀态/資料排程: 資料可用性 - 資料一緻性 - 資料分片
  • DevOps與自動化運維: 基于上述的基礎完成一系列的開發 - 版本送出 - 單元測試 - 打包 - 內建測試 - UI測試 - 釋出測試環境 - 預生産環境釋出 - 灰階釋出 - 正式釋出.
分布式架構設計概要總結
業務服務化設計
  • 性能設計
  • 彈力設計(高可用技術)
  • 業務設計
  • 全棧系統監控
分布式面臨需要解決的問題
技術架構面臨的問題
  • 服務節點如何崩潰恢複
  • 分布式緩存問題
  • 共識問題
  • 流量控制(降級限流等政策)
  • 整體架構的監控
  • 自動化運維
服務化架構面臨的問題
  • 資料一緻性與分布式事務
  • 共享資源與分布式鎖
  • 服務治理
  • 服務持續內建流程(DevOps)
  • 服務架構的垂直拆分粒度以及産生的資料一緻性問題

其實,在這裡僅提供一個思考的次元去分析我們的系統服務,在做分布式架構設計的時候,需要在宏觀上搭建好技術基礎骨架,進行業務分析并結合引入的服務化基礎去思考我們架構可能存在的問題并驗證設計的合理性與适用性。

分布式理論知識

在分布式架構設計中,為了解決上述帶來的問題,我們需要借助分布式技術已有的基礎理論知識來指導并促進我們問題的解決。

其中分布式依賴的基礎理論知識主要有以下兩方面:

分布式理論基礎
  • 拜占庭将軍解決共識問題
  • CAP&BASE理論
  • ACID&2PC&3PC
分布式協定與算法
  • Paxos算法
  • Raft算法
  • 一緻性hash算法
  • Gossip協定
  • Quorum NWP算法
  • PBFT算法
  • zookeeper的ZAB協定

繼續閱讀