分散式系統設計:簡介
當今世界的持續在線的應用程序和API具有可用性和可靠性要求,在幾十年前這些特性在全球範圍內僅少量關鍵任務服務需要。同樣,服務的快速,病毒式增長的潛力意味著每一個應用程序都必須按照用戶的需求立即進行擴展。這些限制和要求意味著幾乎所有的應用程序(無論是消費者移動應用程序還是後端支付應用程序)都需要構建成為分散式系統。
但構建分散式系統具有挑戰性。通常,他們是一次性定製解決方案。通過這種方式,在開發現代面向對象編程語言之前,分散式系統開發與軟體開發領域具有驚人的相似之處。幸運的是,隨著面向對象語言的發展,技術進步已經大大減少了構建分散式系統的挑戰。在這種情況下,容器和容器協調器的普及程度越來越高。與面向對象編程中的對象概念一樣,這些集容器化構建模塊是開發可重用組件和模式的基礎,可以大大簡化和構建可靠的分散式系統的實踐。在下面的介紹中,我們簡會要介紹了導致今天發展現狀的緣由。
系統開發簡史
一開始,有些機器是為特定目的而建造的,例如計算火炮表或潮汐,破碼或其他精確,複雜但死記硬背的數學應用。最終,這些專用機器演變成通用可編程機器。最終他們從一次只能運行一個程序升級為通過分時操作系統在單台機器上運行多個程序,但這些機器仍然彼此分離。
逐漸地,機器互聯在一起,客戶機 - 伺服器體系結構誕生了,因此辦公桌上的相對較低功率的機器可以用於利用另一個房間或建築物中大型機的更大功率。雖然這種客戶機-伺服器編程比為單個機器編寫程序要複雜一些,但理解它仍然相當簡單。客戶提出請求,伺服器為這些請求提供服務。
在二十一世紀初期,網際網路和由數千台相對低成本的商用計算機互聯組成的大型數據中心的發展引起了分散式系統的蓬勃發展。與客戶端 - 伺服器架構不同,分散式系統應用程序由運行在不同機器上的多個不同應用程序組或者運行在不同機器上的許多副本組成,所有這些應用程序一起通信以實現像web搜索或零售銷售平台這樣的系統。
由於它們的分散式特性,如果結構合理,分散式系統本質上更加可靠。當架構正確時,他們可以為建立這些系統的軟體工程師團隊帶來更多可擴展的組織模型。不幸的是,這些優勢需要付出代價。這些分散式系統的設計,構建和調試一般會更加複雜。構建可靠的分散式系統所需的工程技能遠遠高於構建移動或Web前端等單機應用程序所需的技能。無論如何,對可靠分散式系統的需求只會繼續增長。因此,對於構建它們的工具、模式和實踐均有相應的需求。
幸運的是,技術的進步也增加了構建分散式系統的便捷性。容器,容器鏡像和容器協調器近年來都變得流行起來,因為它們是可靠分散式系統的基礎和構建塊。使用容器和容器協調器作為基礎,我們可以建立一系列模式和可重用組件。這些模式和組件是我們可以用來更可靠高效地構建系統的工具包。
軟體開發模式簡史
這已經不是軟體行業第一次出現這種轉變。為了更好地了解模式,實踐和可重用組件如何重塑系統開發,有必要查看類似轉換髮生的歷史時刻。
演算法編程的形式化
儘管人們在1962年出版Donald Knuth的系列作品,計算機編程藝術(Addison-Wesley Professional)之前,人們已經有十多年的計算機編程歷史了,這本書標誌著計算機科學發展的一個重要篇章。特別是,這些書包含的演算法不是為任何特定的計算機設計的,而是為了向讀者介紹演算法本身。這些演算法可以適應所用機器的特定架構或讀者正在解決的具體問題。這種形式化是非常重要的,因為它為用戶提供了一個用於構建他們程序的共享工具包,但也因為它表明了程序員應該學習並隨後應用於各種不同環境的通用概念。演算法本身(獨立於任何要解決的具體問題),是值得理解的。
面向對象編程的模式
Knuth的書標誌著計算機程序設計思想中的重要里程碑,演算法代表了計算機程序設計發展的重要組成部分。然而,隨著程序的複雜性增加,編寫單個程序的人數從個位數增加到兩位數,並最終增加到數千,顯然程序化編程語言和演算法不足以滿足現代計算機任務的編程需求。計算機編程中的這些變化導致了面向對象的編程語言的發展,這在計算機程序的開發中提高了演算法對數據可重用性和可擴展性。
針對計算機編程的這些變化,編程的模式和實踐也發生了變化。整個20世紀90年代初至中期,有關面向對象編程模式的書籍大量湧現。其中最著名的是Erich Gamma等人的「四人組」一書,設計模式:可重用的面向對象編程元素。設計模式為編程任務提供了一個共同的語言和框架。它描述了一系列基於介面的模式,可以在各種環境中重用。由於面向對象編程和特定介面的進步,這些模式也可以作為通用的可重用庫來實現。這些庫可以由開發者社區編寫一次,並重複使用,節省時間並提高可靠性。
開源軟體的興起
儘管開發者共享源代碼的概念自計算之初就已經出現,而且自20世紀80年代中期以來正式的免費軟體組織已經存在,但是在20世紀90年代末和21世紀後期,開源軟體才開始興起。雖然開源只與分散式系統模式的發展的聯繫並不十分密切。但是透過開源社區可以越來越清晰地感受到,軟體開發特別是分散式系統開發尤其依賴社區努力。需要注意的是,構成本書所描述模式基礎的所有容器技術都是作為開源軟體開發和發布的。從社區角度來看,描述和改進分散式開發實踐的模式的價值尤其明顯。
模式、實踐和組件的價值
在花費你寶貴的時間閱讀一些我聲稱會改善你的開發實踐的模式、教你新的技能、讓我們面對它並改變你的生活之前,很多人會問:「為什麼設計模式和實踐可以改變我們設計和構建軟體的方式?「。在這一節中,我將闡述我認為這是一個重要話題的原因,並希望說服你在本書的其餘部分堅持讀下去。
站在巨人的肩膀上
作為一個起點,分散式系統模式的價值在於提供一個站在巨人的肩膀上的機會。我們解決的問題或我們構建的系統很少是完全獨一無二。但最終,我們放在一起的組合和軟體所能實現的整體業務模式可能是世界以前從未見過的。但是,系統建立的方式以及它所追求的問題,想渴望可靠,敏捷和可擴展性並不是新事物。
那麼,這就是模式的第一個價值:它們允許我們從別人的錯誤中學習。也許你以前從未構建過分散式系統,或者你從未構建過這種類型的分散式系統。與其希望一位同事在這方面有一些經驗或者通過其他人曾經犯過同樣的錯誤來學習,你可以讓模式作為你的指導。學習分散式系統開發的模式與學習計算機編程中的其他最佳實踐相同。它可以加速您構建軟體的能力,而不需要您直接了解系統,錯誤,直接的學習編寫模式才是最重要的。
討論項目的共同語言
了解和加速我們對分散式系統的理解僅僅是擁有一組共享模式的第一個價值。即使是對於有經驗的分散式系統開發人員來說模式也是有價值的。模式提供了一個共享辭彙表,使我們能夠快速地相互理解。這種理解是知識共享和進一步學習的基礎。
為了更好地理解這一點,假設我們都使用同一個對象來建造我們的房子。我把這個對象稱為「foo」,當你把那個對象叫做「bar」時,我們會花多長時間來討論foo與bar的值,或者試圖解釋它們的不同,直到我們發現我們在談論同一個對象。只有等我們確定「foo」和「bar」是相同的,我們才能真正開始從彼此的經驗中學習。
如果沒有共同的辭彙,我們就會把時間浪費在「暴力的爭論「中,或是解釋別人通過另一個名稱理解的同一個概念。因此,模式的另一個重要價值是提供一組通用的名稱和定義,這樣我們就不會浪費時間擔心命名,而是直接討論核心概念的細節和實現。
我經常能看到這種情況。後面,sidecar容器的概念(在本書2章所描述的)在容器社區在內部使用。正因為如此,我們不必再花時間去定義它是什麼意思,而是立即跳轉到如何使用概念來解決特定問題。「如果我們只是使用sidecar」......「是的,而且我知道是我們可以使用的容器。」這個例子導致了模式的第三個價值:構建可重用組件。
共享組件輕鬆實現復用
除了使人們能夠從別人身上學習並提供用於討論構建系統藝術的共享辭彙,模式為計算機編程提供了另一個重要工具:找到只需實現一次的通用組件的能力。
如果我們必須完全使用自己的代碼創建我們的程序,我們永遠不會完成。事實上,我們幾乎沒有開始。今天,所有曾經出現過的系統都是站在數千人的肩上,依靠前人的努力而實現的。事實上,操作系統、印表機驅動程序、分散式資料庫、容器運行時環境、容器協調器的代碼以及我們今天構建的整個應用程序,都是使用可重用的共享庫和組件構建的。
模式是定義和開發這些可重用組件的基礎。演算法的形式化使得排序和其他規範演算法的實現的可重用。基於介面的模式的定義促進了一個通用的、面向對象的庫來實現這些模式。
認清分散式系統的核心模式使我們能夠構建共享的通用組件。使用基於HTTP的介面將這些模式實現為容器鏡像意味著它們可以在許多不同的編程語言中重用。當然,構建可重用組件可以提高每個組件的質量,因為共享代碼庫可以充分使用這些組件來發現錯誤和弱點,並提供足夠的關注以確保它們得到修復。
總結
分散式系統需要實現現代計算機程序所期望的可靠性,靈活性和可擴展性。分散式系統設計以後更多地是由巫師實施的黑魔法,而不是非專業人士所應用的科學。常見模式和實踐的確定已經規範並改進了演算法開發和面向對象編程的實踐。本書的目標是為分散式系統做同樣的事情。
推薦閱讀:
※用zookeeper來構建的一種一致性副本協議
※集群資源調度系統設計架構總結
※閱讀筆記:PowerGraph: Distributed Graph-Parallel Computation on Natural Graphs
※分散式系統論文筆記目錄
※Elasticell和Jepsen測試