分佈式系統設計模式

概述

這篇文章是對於【分佈式系統設計模式】的我的理解和部分翻譯。node

文章探討了關於《基於容器化軟件組件的微服務架構》。算法

其實容器化編程的發展路徑和麪向對象編程有殊途同歸之妙--
都是將複雜的系統進行抽象、解耦,而後經過必定的方式組合起來。編程

既然咱們要組合,確定會有面對不一樣狀況的不一樣組合方式。因此,這些不一樣的組合方式也會有幾個經常使用的固定模式。
而這個正式咱們要探討的--分佈式系統設計模式。segmentfault

說到分佈式,第一個聯想到的應該就的容器化。
爲何?其實容器化和分佈式本沒有交集,只是由於咱們發現容器化是一個實現分佈式的高效的方法。設計模式

容器化設置了一個自然的邊界,邊界以外用接口進行通訊。
有了這個邊界的好處就是,任何意料以外的狀況均可以被限制在最小的影響範圍,畢竟咱們構建的是一個大型的複雜系統。安全

我認爲,用FMEA模型能很好的描述爲何會採用容器化去解構分佈式系統。(FMEA,能夠理解爲:失控的狀態必定會發生,咱們要作的是控制失控的範圍)架構

因此,咱們接下來要說的設計模式基本上都是和容器相關,咱們須要把容器做爲一等公民去看。
畢竟這是寫 Kubernetes 的哥們寫的。app

單容器管理者模式 (Single-container management patterns)

咱們爲容器增長一些可控接口,好比 run(), stop(), pause(),使得容器對外來講是可控的。負載均衡

也正是由於普遍的 http 協議支持,你徹底能夠經過 http 和 JSON這樣的序列化方式去構造你應用的對外的 API。框架

通常來講咱們的設計方針都是一個容器提供一種服務。同時容器會爲其上下游提供接口。

什麼接口?

向上,提供容器自己豐富的信息接口。可以爲特定的監控容器運行狀態的應用提供信息。

向下,提供了控制容器自己的接口。使得分佈式系統可以更有效的管理整個應用的生命週期,以及應用的優先級。

好比,一個集羣的管理系統,可以設置集羣處理任務的優先級。(好比 K8s 中的搶佔式調度)

因此一旦採用這種模式的話,你會須要一個統一的管理平臺,經過接口去管理(組管理)單個容器。

單節點-多容器應用模式 (Single-node, multi-container application patterns)

這種模式比較好理解,有些容器應用是須要「共生」的,因此咱們會將其放在同一個節點上。
一旦這樣,分佈式系統會對容器組作聯合調度。
好比 K8s 裏將調度單位描述成了 Pods(一個 Pod 可能包含多個容器),Nomad 則稱其爲 task groups。
下面幾個就是經常使用的單節點多容器的設計模式:

副載模式(Sidecar pattern)

多容器部署最通用的一種模式,就是 sidecar 模式。
其實你們都直接稱呼 Sidecar 模式,不會翻譯成副載。

那 Sidecar 是個啥樣子呢?

舉個例子吧:咱們有一個主容器是 Web Server,咱們須要收集 Web Server 所產生的日誌。
因此咱們會有一個專門的 sidecar 容器,負責收集日誌並把日誌存儲到集羣的存儲系統。
圖片描述

另一個例子,就是主容器的內容呈現,是由一個 sidecar 容器去實時同步的。

還有個例子是爲一個 Http Web Server 提供 Https 功能。
圖片描述

你會發現 Sidecar 是主容器的一種擴展和升級,這種模式的好處在於,由於是容器隔離,因此可以保證從屬容器不會在主容器須要資源的時候佔用過多的資源,由於分配資源的最小單位就是容器。同時,sidecar 通常在功能上比較專職,又是容器化的,因此能夠很方便的進行單獨的部署、升級。

大使模式(Ambassador pattern)

圖片描述

大使模式實現方式是在節點中增長一個通信代理。他解決的問題是:
爲某些年久失修的外部服務,增長一個調用代理,調用者是咱們節點上的應用。

大使模式給開發者的好處是:

  1. 他們只要考慮應用與本地服務的鏈接
  2. 他們能夠在本地進行測試
  3. 調用的外部服務語言無關

其實有個很典型可是非容器化的例子,就是 Ribbon 中的客戶端負載。
和大使模式很像,全部的請求流量都先經由客戶端的負載均衡器決定了流量流向--咱們在大使容器中現決定流量流向,而後直接調用真正的服務。

聰明的你會發現,咱們彷佛能夠在大使容器中作不少手腳,好比熔斷,路由,流量監控,安全控制等等(有點像服務端的 API 網關)。

沒錯,因此咱們得出了一些使用該模式的場景(來自docs.microsoft.com/en...):

  • 客戶端鏈接語言無關,框架無關
  • 將客戶端鏈接的問題與應用分離,解耦開發
  • 爲年久失修的應用程序提供雲或集羣支持

適配器模式(Adapter pattern)

和 Ambassador 相比,Adapter 模式向外部呈現了一個統一的接口。(方向反了一下)

最典型的例子應該就是容器管理平臺,全部系統中的容器都會有一套統一的監控接口。
圖片描述

如今的容器多種多樣,不過只要保證每一個容器都有統一的不變的對外監控接口,對於單獨的監控工具來講就不難實時收集各個容器的數據了。

單節點多容器的模式主要就是上面三種。

多節點應用模式 (Multi-node application patterns)

和單節點多應用模式同樣,咱們一樣要求實現這個模式的系統支持 K8s 中 Pod 這樣的概念。

領導人選舉 (Leader election pattern)

在分佈式系統中,老生常談的問題了,就是領導人選舉。

通常領導人選擇是怎樣一種狀態呢?就是在分佈式系統中,存在一個或者多個領導人,還有剩下的做爲工做節點。
一旦有領導人節點掛了,工做節點按照必定算法升級成爲領導人節點。

領導人選舉算法是十分複雜的算法(至少對我來講),甚至有些算法庫仍是語言限定的,因此,更好的方式就是經過容器去使用這個領導人選舉功能。

那爲何要分爲領導節點和工做節點呢?

固然是爲了更好分配任務,分配好了任務,就能保證系統處在一個高效的狀態下運行。避免出現有些工做節點空閒,有些工做節點忙的現象。整個模式的思想仍是中心化治理最高效的方針。

工做隊列模式 (Work queue pattern)

我以爲,分佈式系統中的工做隊列模式,其實表達了一個具備拓撲關係的分佈式系統。每一個步驟都是單獨的,可是他們的輸入可能須要依靠上一個輸出,亦或者,他們的輸出會成爲下一個的輸入。

這個模式好在他語言無關,我只要知道個人容器的輸入輸出,而後將它放在合適的位置就能夠了。

同時還須要一個專門進行做業管理的容器進行任務的分發。
圖片描述

我在網上並無找到過多的關於描述 Work queue pattern 的資料。
彷佛這種設計模式的叫法不太同樣。

向量化模式 (Scatter/gather pattern)

這是一種有點廣播競爭的模式。

一個外部請求會先被髮送到一個「根」或「父」節點。
而後根節點擴散請求並讓服務端同時進行競爭,而後每一個競爭者都會返回一部分請求的結果,根節點再把碎片結果揉成一個完整的返回。

這樣的模式其實對於開發者的要求仍是比較高的,由於要對分佈式任務處理中產生的異常有很好的把控,同時涉及到了分佈式任務一致性。

通常實現這種模式須要至少 2 個容器,一個是用來進行任務分發的,還有一個是進行結果歸總的。

總結

面向對象編程須要面向對象的設計模式做爲支撐。
容器化的分佈式系統也同樣,須要容器的設計模式做爲支撐。

上面咱們分析了三種容器架構下的設計模式,一共 7 種。
上面這 7 中模式會以組合的形式出如今分佈式系統之中,畢竟分佈式系統是一個複雜系統。

這篇文章所依據的論文,雖然說是分佈式系統的設計模式,可是其實會涉及到不少經典的企業集成模式。因此我在這裏向你們推薦一本書《企業集成模式》
可別覺得是講企業管理的,這是給開發者看的。

好吧,暫時先這樣吧。

參考

相關文章
相關標籤/搜索