雲原生時代|分散式系統設計知識圖譜(內含 22 個知識點)
我們身處於一個充斥著分散式系統解決方案的計算機時代,無論是支付寶、微信這樣頂級流量產品、還是區塊鏈、IOT等熱門概念、抑或如火如荼的容器生態技術如Kubernetes,其背後的技術架構核心都離不開分散式系統。
為什麼要懂分散式架構
系統學習分散式架構設計對於技術人的成長非常關鍵,對於雲原生開發者而言如何設計出符合雲原生設計哲學的應用往往離不開分散式系統知識與方法論的運用。如何設計出高彈性、可配置、可分佈、高效能、高容錯、更安全、更韌性、快交付的原生應用往往是衡量開發者水準的重要參考。
然後而分散式系統是一個很大的概念,從架構設計、研發流程、運維部署、工程效率等多個角度均有很深的知識可以挖掘,學習成本和難道相對較大。近期整理了過去閱讀過的一些和分散式相關書刊和文章,加上自己做分散式開發的一些的心得分享給大家,本文作為開篇,總體上給出知識概覽,後續將分篇結合程式碼實踐來進行闡述。起草倉促,水平有限,歡迎大家一起學習指正。
分散式系統大圖
一、設計
閘道器模式,Gateway
功能
- 請求路由,客戶端直接呼叫 Gateway,Gateway 負責路由轉發到註冊服務上
- 服務註冊,後端服務將 API 註冊,Gateway 負責路由
- 負載均衡,支援多種負載策略
- round robin
- 隨機均衡演算法
- 多權重負載
- session 粘連
- 其它
- 安全特性,支援 HTTPS,賬戶鑑權,及其它安全特性支援
- 灰度釋出,可以針對服務版本或者租戶等特性做灰度釋出
- API 聚合,將多個後端介面聚合,減少客戶端呼叫次數
- API 編排,通過編排來串接多個 API 完成特定業務
設計要點
- 可用性,必須保證高可用
- 擴充套件性,可以靈活擴充套件以支援特定業務比如特定業務流控
- 高效能,通常使用非同步 IO 模型框架實現,比如 Java netty,Go Channel
- 安全,如加密通訊,鑑權,DDOS 防禦等
- 運維
- 應用監控,包括容量,效能,異常檢測等
- 彈性伸縮,具備高彈效能力,以低成本應對高峰值
- 架構
- 與業務解耦合,提供擴充套件擴充套件機制比如 Plugin,Serverless 的思路支援後端業務
- 服務隔離,可以按照後端服務劃分閘道器,做到不同服務使用不同閘道器
閘道器部署靠近後端,保證網路損耗最小,效能最佳
邊車模式,Sidecar
價值
- 分離控制與邏輯,分離業務邏輯與路由,流控,熔斷,冪等,服務發現,鑑權等控制組件
- 適用場景
- 老系統改造擴充套件,Sidebar 程序與服務程序部署在同一個節點,通過網路協議通訊
- 多語言混合分散式系統擴充套件
應用程式由多方提供
設計要點
- 標準服務協議,Sidebar 到 Service,Sidebar 到 Sidebar 協議儘可能與語言解耦
- 聚合控制邏輯比如流控,熔斷,冪等,重試,減少業務邏輯
不要使用對服務侵入的方式進行程序間通訊如訊號量,共享記憶體,優先使用本地網路通訊的方式比如 TPCP 或者 HTTP
服務網格,Service Mesh
新一代微服務架構,本質是服務間通訊的基礎設施層。
架構圖
特點
- 應用間通訊中間層
- 輕量級網路代理
- 解耦應用程式
應用程式無感知
主流框架
- Istio
Linkerd
分散式鎖
解決方案
- Redis分散式鎖,SETNX key value PX expiretime
- value 生成,最好全域性唯一比如TraceID,可以使用/dev/urandom生成
- expiretime單位是毫秒,過期鎖自動釋放 ,鎖持有者保證過期時間內爭搶資源完成計算
- 悲觀鎖,先獲取鎖,再進行操作,吞吐量底
- 樂觀鎖,使用版本號方式實現,吞吐量高,可能出現鎖異常,適用於多讀情況
CAS,修改共享資料來源的場景可以代替分散式鎖
設計要點
- 排他性,任意條件只有一個client可以獲取鎖
- 鎖有自動釋放方式,比如超時釋放
- 鎖必須高可用,且持久化
- 鎖必須非阻塞且可重入
- 避免死鎖,client最終一定可以獲取鎖,不存在異常情況鎖無法釋放的情況
叢集容錯性,叢集部分機器故障,鎖操作仍然可用
配置中心
- 靜態配置,環境及軟體啟動配置
動態配置,執行時動態調整的配置如流控開關,熔斷開關等
非同步通訊
- 請求響應式,傳送方直接向接收方傳送請求
- 傳送方主動輪詢
- 傳送方註冊一個回撥函式,接收方處理完成後回調發送方
- 事件驅動設計(EDA)
- 訊息訂閱,傳送方釋出訊息,接收方訂閱並消費訊息
- Broker 中間人,傳送方向Broker釋出訊息,接收方向Broker訂閱訊息,彼此解耦,比如中介軟體RocketMQ
- 事情驅動設計優勢
- 服務間依賴解除
服務隔離程度高
冪等性
- 本質是一個操作,無論執行多少次,執行結果總是一致的
- 冪等核心是全域性唯一ID,鏈路依據全域性ID做冪等,依據業務複雜度可以選取多種實現方式
- 資料庫自增長ID
- 本地生成uuid
- Redis生產id
- Twitter開源演算法 Snowflake
HTTP冪等性,除POST外,HEAD,GET,OPTIONS,DELETE,PUT均滿足冪等
二、效能
分散式快取
- 快取更新模式
- Cache Aside,常用模式,應用要維護快取的失效,命中,更新等動作
- Read/Write Through,快取代理更新資料庫操作,應用視角只有一份儲存
Write Behind Cache,IO加速方式之一,更新操作只在內測完成,非同步進行批量更新資料庫
非同步處理
- Push模型,中心排程,複雜度高
- Pull模型,無中心排程,複雜度底
Push+Pull模型
資料庫擴充套件
- 資料庫分片
- 垂直分片
- 欄位拆分,將變化頻率不同的欄位拆分到不同表
- 水平分片
- 雜湊演算法來分,資料離散度高,降低熱點可能性
- 通過時間範圍分片,保證資料連續性
- 按照業務種類劃分,比如資料分類,租戶分離等
- 分片設計要點
- 分片要預留足夠空間,避免重新分片
- 分片聚合要並行去做
業務儘可能不去做跨分片的事務
三、容錯
系統可用性
- 垂直分片
- MTTF, Mean Time To Failure,系統平均執行多長時間才發生故障,越長越好
- MTTR,Mean Time To Recover, 故障平均修復時間,越短越好
可用性計算公式, Availability= MTTF /(MTTF+MTTR)
服務降級
- 降低一致性
- 強一致性,將所有的同步一致性,切換為最終一致性,提高吞吐量
- 弱一致性,必要時候犧牲一致性換取服務整體可靠性
- 關閉次要服務
- 不同應用,關閉次要應用,釋放物理資源
- 相同應用,關閉應用次要功能,更多資源給到核心功能
- 簡化服務功能
如簡化業務流程,減少通訊資料等
服務限流
- 限流目的
- SLA保證方式之一
- 應對突發峰刺流量,一定程度節約容量規劃成本
- 租戶隔離策略之一,避免某些使用者佔用其它使用者的資源,導致服務大範圍不可用
- 限流方式
- 服務降級
- 服務拒絕
- 解決方案
- 服務權重劃分,多租戶環境將資源按權重劃分,保證重要客戶的資源
- 服務延時處理,加入服務緩衝佇列延緩服務壓力,用於削峰
- 服務彈性伸縮,依賴服務監控,彈性伸縮容
- 流控演算法
- 計數器
- 單機或者叢集儲存某使用者某時間段請求數,達到閾值則觸發流控
- 佇列演算法
- FIFO佇列
- 請求速度波動,消費速度均勻,佇列滿則流控
- 權重佇列
- 按服務劃分優先順序佇列,不同佇列權重不同
- 佇列演算法設計關鍵:佇列長度的預設非常關鍵
- 佇列太長,流控未生效,服務已經被打死
- 佇列太短,流控被頻繁觸發,體驗差
- FIFO佇列
- 漏斗演算法
- 本質上是佇列+限流器實現,限流器保證消費速度均勻類TCP sync backlog
- 轉發速度均勻
- 令牌桶
- 中間人已恆定速率向桶裡發放令牌,服務請求拿到token則開始服務,否則不處理
- 轉發速度不均勻,流量小時積累,流量大時消費
- 動態流控
- 實時計算服務能力如QPS,對比服務RT如果RT過大,則減少QPS
- 計數器
- 設計要點
- 手動開關,主動運維和應急使用
- 監控通知,限流發生時干係人要清楚
- 使用者感知,如返回特定錯誤資訊(錯誤code/錯誤提示)
鏈路標識,RPC鏈路加入限流標識方便上下游業務識別限流場景做不同處理
熔斷設計
- 場景
- 過載保護,系統負載過高情況為防止故障產生,而採取的一種保護措施
- 防止應用程式不斷嘗試可能會失敗的操作
- 三個狀態
- Closed,閉合狀態,正常狀態,系統需要一個基於時間線到錯誤計數器,如果錯誤累計達到閾值則切換至Open狀態
- Open,斷開狀態,所有對服務對請求立即返回錯誤,不用呼叫後端服務進行計算
- Half-Open,半開狀態,允許部分請求流量進入並處理,如果請求成功則按照某種策略切換到Closed狀態
- 設計要點
- 定義觸發熔斷的錯誤型別
- 所有觸發熔斷的錯誤請求必須要有統一的日誌輸出
- 熔斷機制必須有服務診斷及自動恢復能力
- 最好為熔斷機制設定手動開關用於三種狀態的切換
熔斷要切分業務,做到業務隔離熔斷
補償事務
- CAP
- 一致性(Consistence)、可用性(Availability)、分割槽容忍性(Partition Tolerance)
- BASE
- Basic Availabillity,基本可用
- Soft State,軟狀態
- Eventual Consistency,最終一致性
- Design For Failure
Exponential Blackoff,指數級退避
四、DevOps
部署
- 基礎設施
- 雲
- 公有云
- 私有云
- 混合雲
- 容器技術
- Docker
- Kubernetes
- 雲
- 部署策略
- 停機部署
- 滾動部署
- 藍綠部署
- 灰度部署
A/B 測試
配置管理
- Ansible
- Puppet
Shippable
監控
- Nagios
DynaTrace
CI與CD
五、工程效率
敏捷管理
Scrum
持續整合
- Jenkins
CodeShip
持續交付
寫在最後
分散式系統在阿里巴巴經濟有著廣泛的應用,以筆者所在的彈性技術團隊為例,當業務足夠規模化後,最終面臨的技術問題都是通過踐行分散式系統架構的設計理念和方法輪得以解決,可以說分散式系統架構的知識與方法論是當前網際網路應用規模化後的通用解決方案。
學習分散式系統設計也不是一蹴而就,需要不斷汲取理論知識,然後將理論不斷付諸實踐,最終通過一次次的調優來將知識的價值最大化。筆者最後的建議是先理論、後實踐、重實踐、不妥協,所謂紙上得來終覺淺,絕知此事要躬行,與君共勉。
“ 阿里巴巴雲原生微信公眾號(ID:Alicloudnative)關注微服務、Serverless、容器、Service Mesh等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術公眾號。”