[轉]分散式系統架構知識體系
註明:原文由【薛定諤貓】發表於其個人微信公眾號【架構師是怎樣煉成的】中。
雙十一終於過去了,趁雙十二的需求還沒下來前,晚上稍微有點時間搞點自己的事情了,距離上篇微信公眾號文章已經過去快三個月了,今天決定寫一篇關於分散式知識體系的文章,分散式架構整個知識體系紛繁複雜,不加以總結很難形成知識網路.我將從基礎理論,系統設計,高可用三方面總結分散式知識體系.
基礎理論
1. 節點與網路
- 節點
傳統的節點指的是一臺單體的物理機,包含所有的服務及資料庫(即傳統的單體應用),隨著虛擬化的發展,單臺物理機上可以部署多臺虛擬機器,實現資源利用的最大化,節點也變成了單臺虛擬機器上的服務,目前隨著容器技術的成熟,服務逐步在容器化(目前阿里的服務已100%容器化,基於自研的pouch容器,此容器已開源),也就是節點只是輕量級的容器服務.總體來說,節點就是能提供單位服務的邏輯計算資源的集合. - 網路
分散式架構的根基是網路,不管是區域網還是公網,沒有網路一切都無從可談,對於網路需要至少熟悉傳輸層(TCP)與應用層(Http)常見協議
2. 一致性理論
2.1 強一致性理論ACID
- Atomicity:原子性一個事務中的所有操作,要麼全部完成,要麼全部不完成,不會結束在某個中間環節
- Consistency:一致性是指事務使得系統從一個一致的狀態轉換到另一個一致狀態,在事務開始之前和結束之後,對資料庫沒有完整性沒有破壞
- Isolation:隔離性,併發事務之間互相影響的程度,資料庫允許多個併發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行導致的資料不一致(髒讀,可重複讀,幻讀,序列化)
- Durability:永續性 事務處理結束後,對資料的修改書永久性的,即使系統故障也不會丟失(除非所有的備份磁碟都永久損壞了)
2.2 分散式一致性CAP
分散式環境下,我們無法100%保證網路正常連線和資訊的傳送(畢竟網路是不可靠的),於是發展出了CAP/FLP/DLS三個重要理論
- CAP:分散式計算系統不可能同時保證一致性(Consistency),可用性(Avaliablity),分割槽容忍性(Partition),只能做出取捨,保證兩個.
- FLP:在非同步環境中,如果節點間的網路延遲沒有上限,只要有一個惡意的節點存在,就沒有演算法能在有限的時間內達成共識.
- DLS:
1)在一個部分同步的網路模型(網路延時有界限但是我們不知道在哪裡)下的協議可以容忍1/3(拜占庭)任意錯誤.
2)在一個非同步模型中的確定性的協議(沒有網路延時上限)不能容錯.
3)同步模型的協議(網路延遲可以保證小於已知時間)可以達到100%錯誤.
2.3 弱一致性Base
多數情況下,其實我們也並非要求強一致性,部分業務也可以容忍一定程度的延遲一致,所以為了兼顧效率,發展出來的最終一致性BASE理論,BASE是指基本可用Basically Available),軟狀態(Soft State),最終一致性(Consistency)
- 基本可用Basically Available):分散式系統在出現故障的時候,允許損失部分可用來保證核心可用.
- 軟狀態(Soft State):指允許系統存在中間狀態,而該中間狀態不會影響系統整體可用性,分散式儲存中一般資料至少會有三個副本,允許不同節點副本同步的延時就是軟狀態的體現.
- 最終一致性(Consistency):最終一致性是指系統中所有資料副本經過一定時間後,最終能夠達到一致的狀態.弱一致性和強一致性相反,最終一致性是弱一致性的一種特殊情況.
2.4 一致性演算法
一致性演算法是分散式系統最核心本質的內容,包含:
- Paxox(如zookeepr)
- Raft(如etcd,consule)
- Gossip(如redis)
系統設計
1. 檔案系統
單機計算機的儲存始終都有上限,隨著網路的出現,多臺計算機協作儲存檔案的方案也相繼被提出,現代分散式檔案系統的奠基論文是來自Google的《The Google File System》,常見的分散式檔案系統有:
- HDFS
- FastDfS
- Ceph
常見分散式檔案系統(來自維基百科)
2. 資料庫
資料庫其實也資料檔案系統,只是在檔案系統的基礎上增加了事務,檢索等高階特性,所以複雜度更高,傳統的關係型資料庫為了兼顧事務和效能的特性,在分散式方面的發展有限,非關係型資料庫擺脫了事務的強一致性束縛,達到了最終一致性.
- 關係型資料庫:Mysql,Oracle
- 列式儲存:Hbase
- 文件型儲存:ElasticSearch,MongoDb
- KV型別:Redis
3. 計算
分散式計算是在分散式儲存的基礎上,充分發揮分散式系統的資料冗餘備份,多副本高效獲取資料的特性,從而進行計算,把原本需要長時間計算的任務拆分成多個任務並行處理,從而提高效率
- 離線計算:Hadoop
- 實時計算:Spark
- 流式計算:Storm,Flink,Apache Steams
4. 快取
快取作為提升效能的利器無處不在,小到CPU與記憶體之間的快取,大到分散式應用快取,分散式快取系統大大提升了資料訪問時間,帶來的問題是如何保證資料一致性,引入分散式鎖來解決
- 持久化:Redis
- 非持久化:Memchache
5. 訊息
分散式系統需要一個連線元件和服務的訊息傳遞中介軟體,理想情況是鬆耦合的方式,以便最大限度的提高可伸縮性,非同步訊息傳遞被廣泛使用
- Kafka
- RocketMq
6. 日誌
錯誤對於分散式系統來說在家常便飯,在而我們設計系統時本身就需要把容錯作為普遍存在的現象來考慮,那麼當錯誤出現的時候,如何快速定位和恢復就非常重要了.
對於小則幾十個節點,多則幾點節點的分散式叢集來說,將日誌統一收集也是分散式系統必須考慮的,ELK目前已成為標配
- E:ElasticSearch
- L:LogStash
- K:Kibana
高可用
1. 流量排程
1.1 負載均衡
負載均衡是我們對服務如何消化流量的通用設計,通常分為物理層的底層協議分流的硬體負載均衡和軟體層的軟負載均衡,負載均衡解決方案已是業內成熟的方案,我們通常會針對特定業務在不同場景進行優化,常用的負載均衡方案
- F5
- LVS
- Nginx/Tengine(阿里基於Nginx開源)
常用負載均衡演算法:
- 輪詢法(Round Robin)
- 加權輪詢法(Weight Robin)
- 隨機法(Random)
- 加權隨機法(Weight Random)
- 最小連線法(Least Connections)
- 源地址雜湊法(Hash)
- 一致性雜湊法(Consistency Hash)
1.2 閘道器設計
在我們建設好分散式系統後,最先受到考驗的關口就是網關了,我們需要關注系統流量的情況,也就是如何對流量的管理,我們追求的是在系統可容納的流量上限內,把資源留給最優質的流量使用,而把非法惡意的流量攔在門外,這樣在節省成本的同時確保系統不會被衝擊而宕機.
負載均衡首當其衝的就是閘道器,中心化叢集流量最先到的打到的地方就是網關了,如果扛不住的話,那麼整個系統將不可用
- 高效能:閘道器設計第一需要考慮的是高效能的流量轉發,閘道器單節點通常能達到上百萬的併發流量
- 分散式:出於流量壓力分擔和災備考慮,閘道器設計同樣需要分散式
- 業務篩選:網關同設計簡單的原則,排出調大部分的惡意流量
- 請求校驗:請求鑑權攔截非法流量
- API聚合:聚合服務端介面,減少服務呼叫
常用的企業級閘道器有:
- Nginx+_Lua自研閘道器
- Kong
- Zuul閘道器
1.3 流量控制
流量分配
- 計數器
- 佇列
- 漏斗
- 令牌桶
- 動態流控
流量限制:
在流量激增的時候,通常我們需要有流量措施來防止系統出現雪崩,那麼久需要預估系統的流量上限,然後設定好上限數,但流量增加到一定閾值後,多出來的流量則不會進入系統,通過犧牲部分流量來保全啟動的可用性
限流策略
- QPS粒度
- 執行緒數粒度
- RT閾值
- 限流工具:這裡強烈推薦一款阿里今年開源的限流利器Sentinel,歷經雙十一歷練
2. 服務排程
打鐵還需自身硬,做好流量排程後,剩下的就是服務自身的健壯性了
2.1 註冊中心(服務的根據地)
- zookeeper
- etcd
- conule
- eureka
2.2 服務編排
通過訊息的互動序列來控制各個資源的互動,參與互動的資源都是對等的,沒好友集中的控制,微服務環境下服務眾多,我們需要一個總的協調器來協議服務之間的依賴,呼叫關係,k8s是我們的不二選擇
2.3 服務控制
發現:
服務啟動後需要發現註冊中心,並且把自身的服務資訊註冊到閘道器,也即是閘道器接入,註冊中心則會監控服務的不同狀態,做健康檢查,把不可用的服務歸類
降級:
當用戶激增的時候,我們首先在流量端做手腳,也就是限流,當我們發現限流後系統響應變慢了,有可能導致更多問題時,我們需要對服務本身做一些操作,服務降級就是把當前不是很核心的功能關閉掉,或者不緊要的準確性放寬範圍,時候在做一些人工補救
- 降低一致性約束
- 關閉非核心服務
- 簡化功能
熔斷:
當我們做了以上的操作後,還是覺得不放心,那麼就需要對資料再進一步操作.熔斷是對過載的一種自身保護,一般我們的服務依賴的其他的二方服務,有的二方服務可能會因為業務量的突增或者大部分機器宕機導致自己在呼叫此二方服務長時間不能返回,這些長時間不能返回的二方請求會佔用大量的執行緒等資源,造成了其他的並不依賴該二方服務的介面因為資源較少效能嚴重下降,甚至自己的伺服器因為沒資源而崩潰,此時需要對此二方請求進行熔斷,熔斷狀態有
- 閉合狀態
- 半開狀態
- 斷開狀態
- 熔斷工具:Hystrix
3. 資料排程
資料儲存最大的挑戰就是資料冗餘的管理,冗餘多了效率低且佔用資源,副本少了起不到災備的作用,我們通常的做法是把有狀態的請求,通過狀態分離,轉化為無狀態的請求
- 狀態轉移:分離狀態全域性儲存,請求轉換為無狀態流量,比如我們通常會將登陸資訊快取至全域性的redis中,而不需要在多個應用中去冗餘使用者的登陸資料
-
分庫分表:資料橫向擴充套件
- 分割槽分片:多副本冗餘
4. Devops
分散式配置中心:
全域性配置中心按環境來區分,統一管理,減少了多處配置混亂的局面
- Diamond(阿里內部未開源)
- Apollo
- SpingCloud Config
5. 部署策略
微服務部署是家常便飯,如何讓我們的服務更好的支撐業務發展,穩健的部署策略是我們考慮的,如下的部署策略適合不同業務和不同階段
- 停機部署
- 滾動部署
- 藍綠部署
- 灰度部署
- A/B測試
6. 作業排程
作業排程是系統必不可少的環節,傳統的方式是在Linux伺服器上配置crond定時任務或者直接在業務程式碼裡面完成排程任務,現在已有成熟的方案:Elastic-job
7. 全棧監控
由於分散式系統時由眾多機器共同協作的系統,而且網路也無法保證完全可用,所以我們必須建設一套各個環節都能監控的系統,這樣我們才能從底層到各個層面進行監控,出現意外及時修復,不讓我們的系統裸奔
- 基礎層:CPU,I/O,記憶體,執行緒,吞吐,負載,JVM
- 中介軟體:分散式系統接入了大量中介軟體系統,中介軟體本身也需要監控
- 應用層:qps,rt
- 監控鏈路:zipkin,pinpoint,eagleeye等等分散式鏈路跟蹤
註明:本文為轉發文章,原文由【薛定諤貓】發表於其個人微信公眾號【架構師是怎樣煉成的】中。
【架構師是怎樣煉成的】微信公眾號二維碼