Design patterns for container-based distributed systems(HotCloud 2016)
首先介紹下這篇文章的第一作者Brendan Burns,他2008-2016年在Google工作,是Kubernetes的首席工程師,k8s容器編排的主要創始人之一,他在2016年的7月份宣布加入了Microsoft。
第二作者David Oppenheimer,他參與了Google的三大數據中心管理系統的開發——Kubernetes、Omega和Borg的開發,同時也是論文Borg的作者之一。
那篇非常有名的文章《Borg, Omega, and Kubernetes:Lessons learned from three container management systems over a decade》就出自這兩位作者之手。
這篇論文發表在HotCloud 2016(The 8th Usenix Workshop on Hot Topics in Cloud Computing),在2018年的3月份,Brendan Burns出了一本書:《Designing Distributed Systems》,這本書對論文中提到的一些Design Pattern進行了更加詳細的說明,同時本專欄也在不斷的更新這本書,歡迎大家拍磚。
傳送門:分散式系統設計介紹
在20世紀80年代末和90年代初,面向對象編程徹底改變了軟體開發,推廣了將應用程序構建為模塊化組件集合的方法。當下,隨著容器化軟體組件構建的微服務體系結構的日漸普及,憑藉容器與外界的隔離性,容器特別適合作為分散式系統中的基本「對象」。隨著這種架構風格的成熟,作者通過觀察抽象出了更高層次的設計模式。
本文描述了作者在基於容器的分散式系統中觀察到的三種類型的設計模式:
- 用於容器管理的單容器模式
- 用於緊密合作的容器的單節點模式
- 用於分散式演算法的多節點模式。
下面對這三種模式進行簡單的介紹。
1 基於容器管理的單容器模式
容器為介面的定義提供了一個自然邊界(類似於對象的邊界)。 容器不僅可以通過該介面對外開放特定應用程序的功能,而且還可以用來作為顯示管理系統的鉤子。
從容器角度「向上」來考慮,容器可以公開豐富的應用程序信息,包括特定應用的監控指標(QPS、應用程序運行狀況等)、分析開發人員感興趣的信息(threads、stack、 lock contention、 network message statistics等)、組件配置信息和組件日誌。例如,Kubernetes、Aurora、Marathon和其他容器管理系統允許用戶通過指定的HTTP endpoints(例如「/ health」)來定義健康檢查。
從容器角度「向下」來考慮,容器所提供的介面為定義生命周期提供了天然的環境,這使得編寫功能組件變得更加容易。例如,集群管理系統一般都會為任務分配優先順序,對於優先順序高的任務,即使集群中存在超賣的現象,高優先順序任務也要能保證運行,一般是通過搶佔低優先順序作業的資源來實現的,通過kill掉低優先順序作業,但到處可能會出現的任務死亡給開發帶來了負擔。相反,如果在應用程序和管理系統之間定義了一個正式的生命周期,那麼應用程序組件會變得易於管理,例如,Kubernetes使用Docker的「優雅刪除」功能,在發送SIGKILL信號之前的一段時間,通過給容器發送SIGTERM信號來警告容器它將被終止,這留給了容器一定的時間來完成正在進行的操作並將狀態刷新到磁碟。這種機製為狀態序列化和恢復提供了支持,使得分散式系統的狀態管理變得更加容易。
2 用於緊密合作的容器的單節點模式
除去單個容器的介面之外,作者還看到了跨容器的設計模式,作者在15年的一篇博客上有探討過幾種模式:The Distributed System ToolKit: Patterns for Composite Containers。這些單節點模式由共同調度到同一台主機上的共生容器組成,容器管理系統支持將多個容器共同調度為一個原子單元,在Kubernetes中稱為Pod。
2.1 Sidecar pattern
第一種也是最常見的多容器部署模式就是sidecar pattern,有些文章將其翻譯為挎斗模式,就像是老式的摩托車,旁邊會有一個小的挎斗,能讓車多坐一個人。Sidecar容器就是像摩托車上的那個挎斗一樣,用來延伸和增強主容器。例如,主容器可能是一個Web伺服器,它可能與一個「logsaver」sidecar容器配對,該容器從本地磁碟收集Web伺服器的日誌並將它們傳輸到集群的存儲系統。下圖顯示了sidecar模式的一個例子。
另一個常見的例子是一個Web伺服器,它服務於本地磁碟內容,該sidecar容器定期同步來自git存儲庫、內容管理系統或其他數據源的內容。這兩個例子在Google都很常見。由於同一台計算機上的容器可以共享本地磁碟卷,因此可以使用Sidecars。
雖然說可以將Sidecars容器裡面的功能構建到主容器當中(例如將log saver的功能在主容器中實現),但是將主容器和Sidecars容器分開有以下幾點好處:
- 容器是資源計數和分配的單位。
- 容器是packing的單元。因此可以將服務和日誌存儲分隔到不同的容器中,可以很容易地在兩個獨立的編程隊伍之間分配其開發的責任,並且可以進行單獨和一起測試。
- 容器是重用的單元。所以Sidecars容器可以與不同的主容器進行配對,保證了可重用性。
- 容器提供了一個故障遏制的邊界。這樣出現問題時可以使得整個系統進行優雅地降級。
- 容器是部署的單位。它允許每個功能都可以獨立地進行升級或者回滾
以上提到的五個優點適用於該論文中提到的所有容器模式。
2.2 Ambassador pattern
第二種模式是Ambassador pattern,也成為外交官模式或大使模式。這種模式主要利用同一Pod中的容器可以共享相同的localhost網路介面的特性。如下圖所示,在一個Pod中給應用容器搭配一個大使容器作為代理伺服器,大使容器幫助應用容器訪問外部服務,使得應用容器訪問服務時不需要使用外網的IP地址,而只需要用localhost訪問本地服務。在這種模式下,作為代理伺服器的大使容器很像外部服務派駐在Pod中的「大使」,使得應用容器辦理業務時只需要跟本Pod的大使打交道就可以了。
這種大使模式通過三種方式簡化了開發人員的工作:
- 他們只需要考慮並編程連接到本地主機上的單個伺服器的應用程序。
- 他們可以通過在本地機器上運行真正的程序實例來測試其應用程序的獨立性,而不是使用大使容器。
- 他們可以將大使容器與其他不同的主程序放在一起進行重用。
2.3 Adapter pattern
第三種模式是適配器模式。這種模式對於監控和管理分散式系統尤為重要,與大使模式不同的是,適配器模式對外界展示了一個簡化的應用視圖,它通過多個容器來標準化輸出和標準化介面實現這一點。如下圖所示,適配器模式常見的一個例子是確保系統中的所有容器具有相同的監控介面。當今的程序使用各種方法來導出其度量標準(如JMX,statsd等)。但是,如果所有應用程序都提供了一致的監視介面,單個監視工具就可以更容易地收集、匯總和顯示異構應用程序集中的監控數據。
3 多結點模式
3.1 領導選舉模式
在分散式系統中,最常見的一個問題就是領導選舉。雖然副本(replica)多用於分流進行負載均衡,但是副本另外一個重要的用途就是用來選舉領導者,如果領導者掛了則迅速從剩下的副本中選擇新的領導。現在有很多可以進行領導選舉的庫,但是通常很難理解和使用,並且還受限於不同的編程語言。將領導選舉庫鏈接到應用程序的另一種方法就是使用領導選舉容器。一組領導選舉容器,每個容器與需要領導選舉的應用實例一起調度,可以在他們自己之間進行選舉,並且他們可以通過本地主機向每個需要領導選舉的應用容器提供簡化的HTTP API(例如成為領導者,更新領導力等)。這些領導選舉容器可以構建一次,然後由開發人員重新使用簡化的介面。
3.2 工作隊列模式
雖然說工作隊列像領導選舉一樣已經有很多框架實現了,但它也是分散式系統模式的一個例子,可以從面向容器的體系結構受益。實現run()和mount()介面的容器,其可用性使得實現一個通用工作隊列框架非常簡單,該工作隊列框架可以將任意處理代碼打包為一個容器和任意數據,並構建一個完整的工作隊列系統。開發人員只需構建一個容器,該容器可以在文件系統上獲取輸入數據文件,並將其轉換為輸出文件;這個容器將成為工作隊列的一個階段。所有涉及開發完整工作隊列的其他工作都可以由通用工作隊列框架來處理,該框架可以在需要此類系統時重用。如下圖所示,說明了用戶代碼集成到共享工作隊列框架中的方式。
3.3 分散/聚集模式
最後一個多結點模式是分散/聚集模式。在這樣的系統中,外部客戶端向「根」或「父」節點發送初始請求。該root將請求發送給大量伺服器並行執行計算。每個分片都會返回部分數據,並且root將這些數據收集到原始請求的單個響應中。這種模式在搜索引擎中很常見。開發這樣一個分散式系統涉及大量的樣板代碼:分散請求,收集響應,與客戶端交互等。這些代碼中的大部分都是非常通用的,而且在面向對象的編程中,可以重構通過這種方式可以提供一個可以與任意容器一起使用的實現,只要它們實現了特定的介面就行。特別是,要實現分散/收集系統,用戶需要提供兩個容器:
- 葉節點計算的容器;該容器執行部分計算並返回相應的結果。
- 合併容器;這個容器獲取所有葉子容器的聚合輸出,並將它們分組為單個響應。
通過提供實現這些相對簡單的介面的容器,可以很容易地看到用戶如何實現任意深度的分散/聚集系統(如果需要的話,還包括父項)。
感謝:
感謝@feilengcui008指正出來錯誤。
推薦閱讀:
※各大公司分散式存儲領域相關論文
※OceanBase知乎官方號開通了!
※ZEROC究竟是何方神聖?
※利用DB實現分散式鎖的思路
※分散式系統設計:批處理模式之事件驅動的批處理