Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

4.2 分佈式系統

分佈式系統是自主的計算機網絡,計算機互相通信來完成一個目標。分佈式系統中的計算機都是獨立的,並且沒有物理上共享的內存或處理器。它們使用消息來和其它計算機通信,消息是網絡上從一臺計算機到另一臺計算機傳輸的一段信息。消息可以用於溝通許多事情:計算機可以讓其它計算機來執行一個帶有特定參數的過程,它們可以發送和接受數據包,或者發送信號讓其它計算機執行特定行為。

分佈式系統中的計算機具有不同的作用。計算機的作用取決於系統的目標,以及計算機自身的硬件和軟件屬性。分佈式系統中,有兩種主要方式來組織計算機,一種叫客戶端-服務端架構(C/S 架構),另一種叫做對等網絡架構(P2P 架構)。

4.2.1 C/S 系統

C/S 架構是一種從中心來源分發服務的方式。只有單個服務端提供服務,多臺客戶端和服務器通信來消耗它的產出。在這個架構中,客戶端和服務端都有不同的任務。服務端的任務就是響應來自客戶端的服務請求,而客戶端的任務就是使用響應中提供的數據來執行一些任務。

C/S 通信模型可以追溯到二十世紀七十年代 Unix 的引入,但這一模型由於現代萬維網(WWW)中的使用而變得具有影響力。一個C/S 交互的例子就是在線閱讀紐約時報。當www.nytimes.com上的服務器與瀏覽器客戶端(比如 Firefox)通信時,它的任務就是發送回來紐約時報主頁的 HTML。這可能涉及到基於發送給服務器的用戶賬戶信息,計算個性化的內容。這意味著需要展示圖片,安排視覺上的內容,展示不同的顏色、字體和圖形,以及允許用戶和渲染後的頁面交互。

客戶端和服務端的概念是強大的函數式抽象。服務端僅僅是一個提供服務的單位,可能同時對應多個客戶端。客戶端是消耗服務的單位。客戶端並不需要知道服務如何提供的細節,或者所獲取的數據如何儲存和計算,服務端也不需要知道數據如何使用。

在網絡上,我們認為客戶端和服務端都是不同的機器,但是,一個機器上的系統也可以擁有 C/S 架構。例如,來自計算機輸入設備的信號需要讓運行在計算機上的程序來訪問。這些程序就是客戶端,消耗鼠標和鍵盤的輸入數據。操作系統的設備驅動就是服務端,接受物理的信號並將它們提供為可用的輸入。

C/S 系統的一個缺陷就是,服務端是故障單點。它是唯一能夠分發服務的組件。客戶端的數量可以是任意的,它們可以交替,並且可以按需出現和消失。但是如果服務器崩潰了,整個系統就會停止工作。所以,由 C/S 架構創建的函數式抽象也使它具有崩潰的風險。

C/S 系統的另一個缺陷是,當客戶端非常多的時候,資源就變得稀缺。客戶端增加系統上的命令而不貢獻任何計算資源。C/S 系統不能隨著不斷變化的需求縮小或擴大。

4.2.2 P2P 系統

C/S 模型適合於服務導向的情形。但是,還有其它計算目標,適合使用更加平等的分工。P2P 的術語用於描述一種分佈式系統,其中勞動力分佈在系統的所有組件中。所有計算機發送並接受數據,它們都貢獻一些處理能力和內存。隨著分佈式系統的規模增長,它的資源計算能力也會增長。在 P2P 系統中,系統的所有組件都對分佈式計算貢獻了一些處理能力和內存。

所有參與者的勞動力的分工是 P2P 系統的識別特徵。也就是說,對等者需要能夠和其它人可靠地通信。為了確保消息到達預定的目的地,P2P 系統需要具有組織良好的網絡結構。這些系統中的組件協作來維護足夠的其它組件的位置信息並將消息發送到預定的目的地。

在一些 P2P 系統中,維護網絡健康的任務由一系列特殊的組件執行。這種系統並不是純粹的 P2P 系統,因為它們具有不同類型的組件類型,提供不同的功能。支持 P2P 網絡的組件就像腳手架那樣:它們有助於網絡保持連接,它們維護不同計算機的位置信息,並且它們新來者來鄰居中找到位置。

P2P 系統的最常見應用就是數據傳送和存儲。對於數據傳送,系統中的每臺計算機都致力於網絡上的數據傳送。如果目標計算機是特定計算機的鄰居,那臺計算機就一起幫助傳送數據。對於數據存儲,數據集可以過於龐大,不能在任何單臺計算機內裝下,或者儲存在單臺計算機內具有風險。每臺計算機都儲存數據的一小部分,不同的計算機上可能會儲存相同數據的多個副本。當一臺計算機崩潰時,上面的數據可以由其它副本恢復,或者在更換替代品之後放回。

Skype,一個音頻和視頻聊天服務,是採用 P2P 架構的數據傳送應用的示例。當不同計算機上的兩個人都使用 Skype 交談時,它們的通信會拆成由 1 和 0 構成的數據包,並且通過 P2P 網絡傳播。這個網絡由電腦上註冊了 Skype 的其它人組成。每臺計算機都知道附近其它人的位置。一臺計算機通過將數據包傳給它的鄰居,來幫助將它傳到目的地,它的鄰居又將它傳給其它鄰居,以此類推,直到數據包到達了它預定的目的地。Skype 並不是純粹的 P2P 系統。一個超級節點組成的腳手架網絡用於用戶登錄和退出,維護它們的計算機的位置信息,並且修改網絡結構來處理用戶進入和離開。

4.2.3 模塊化

我們剛才考慮的兩個架構 -- P2P 和 C/S -- 都為強制模塊化而設計。模塊化是一個概念,系統的組件對其它組件來說應該是個黑盒。組件如何實現行為應該並不重要,只要它提供了一個接口:規定了輸入應該產生什麼輸出。

在第二章中,我們在調度函數和麵向對象編程的上下文中遇到了接口。這裡,接口的形式為指定對象應接收的信息,以及對象應如何響應它們。例如,為了提供“表示為字符串”的接口,對象必須回覆__repr____str__信息,並且在響應中輸出合適的字符串。那些字符串的生成如何實現並不是接口的一部分。

在分佈式系統中,我們必須考慮涉及到多臺計算機的程序設計,所以我們將接口的概念從對象和消息擴展為整個程序。接口指定了應該接受的輸入,以及應該在響應中返回給輸入的輸出。

接口在真實世界的任何地方都存在,我們經常習以為常。一個熟悉的例子就是 TV 遙控器。你可以買到許多牌子的遙控器或者 TV,它們都能工作。它們的唯一共同點就是“TV 遙控器”的接口。只要當你按下電院、音量、頻道或者其它任何按鈕(輸入)時,一塊電路向你的 TV 發送正確的信號(輸出),它就遵循“TV 遙控器”接口。

模塊化給予系統許多好處,並且是一種沉思熟慮的系統設計。首先,模塊化的系統易於理解。這使它易於修改和擴展。其次,如果系統中什麼地方發生錯誤,只需要更換有錯誤的組件。再者,bug 或故障可以輕易定位。如果組件的輸出不符合接口的規定,而且輸入是正確的,那麼這個組件就是故障來源。

4.2.4 消息傳遞

在分佈式系統中,組件使用消息傳遞來互相溝通。消息有三個必要部分:發送者、接收者和內容。發送者需要被指定,便於接受者得知哪個組件發送了信息,以及將回復發送到哪裡。接收者需要被指定,便於任何協助發送消息的計算機知道發送到哪裡。消息的內容是最寶貴的。取決於整個系統的函數,內容可以是一段數據、一個信號,或者一條指令,讓遠程計算機來以一些參數求出某個函數。

消息傳遞的概念和第二章的消息傳遞機制有很大關係,其中,調度函數或字典會響應值為字符串的信息。在程序中,發送者和接受者都由求值規則標識。但是在分佈式系統中,接受者和發送者都必須顯式編碼進消息中。在程序中,使用字符串來控制調度函數的行為十分方便。在分佈式系統中,消息需要經過網絡發送,並且可能需要存放許多不同種類的信號作為“數據”,所以它們並不始終編碼為字符串。但是在兩種情況中,消息都服務於相同的函數。不同的組件(調度函數或計算機)交換消息來完成一個目標,它需要多個組件模塊的協作。

在較高層面上,消息內容可以是複雜的數據結構,但是在較低層面上,消息只是簡單的 1 和 0 的流,在網絡上傳輸。為了變得易用,所有網絡上發送的消息都需要根據一致的消息協議格式化。

消息協議是一系列規則,用於編碼和解碼消息。許多消息協議規定,消息必須符合特定的格式,其中特定的比特具有固定的含義。固定的格式實現了固定的編碼和解碼規則來生成和讀取這種格式。分佈式系統中的所有組件都必須理解協議來互相通信。這樣,它們就知道消息的哪個部分對應哪個信息。

消息協議並不是特定的程序或軟件庫。反之,它們是可以由大量程序使用的規則,甚至以不同的編程語言編寫。所以,帶有大量不同軟件系統的計算機可以加入相同的分佈式系統,只需要遵守控制這個系統的消息協議。

4.2.5 萬維網上的消息

HTTP(超文本傳輸協議的縮寫)是萬維網所支持的消息協議。它指定了在 Web 瀏覽器和服務器之間交換的消息格式。所有 Web 瀏覽器都使用 HTTP 協議來請求服務器上的頁面,而且所有 Web 服務器都使用 HTTP 格式來發回它們的響應。

當你在 Web 瀏覽器上鍵入 URL 時,比如 http://en.wikipedia.org/wiki/UC_Berkeley,你實際上就告訴了你的計算機,使用 "HTTP" 協議,從 "http://en.wikipedia.org/wiki/UC_Berkeley" 的服務器上請求 "wiki/UC_Berkeley" 頁面。消息的發送者是你的計算機,接受者是 en.wikipedia.org,以及消息內容的格式是:

GET /wiki/UC_Berkeley HTTP/1.1

第一個單詞是請求類型,下一個單詞是所請求的資源,之後是協議名稱(HTTP)和版本(1.1)。(請求還有其它類型,例如 PUT、POST 和 HEAD,Web 瀏覽器也會使用它們。)

服務器發回了回覆。這時,發送者是 en.wikipedia.org,接受者是你的計算機,消息內容的格式是由數據跟隨的協議頭:

HTTP/1.1 200 OK
Date: Mon, 23 May 2011 22:38:34 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
Last-Modified: Wed, 08 Jan 2011 23:11:55 GMT
Content-Type: text/html; charset=UTF-8

... web page content ...

第一行,單詞 "200 OK" 表示沒有發生錯誤。協議頭下面的行提供了有關服務器的信息,日期和發回的內容類型。協議頭和頁面的實際內容通過一個空行來分隔。

如果你鍵入了錯誤的 Web 地址,或者點擊了死鏈,你可能會看到類似於這個錯誤的消息:

404 Error File Not Found

它的意思是服務器發送回了一個 HTTP 協議頭,以這樣起始:

HTTP/1.1 404 Not Found

一系列固定的響應代碼是消息協議的普遍特性。協議的設計者試圖預料通過協議發送的常用消息,並且賦為固定的代碼來減少傳送大小,以及建立通用的消息語義。在 HTTP 協議中,200 響應代碼表示成功,而 404 表示資源沒有找到的錯誤。其它大量響應代碼也存在於 HTTP 1.1 標準中。

HTTP 是用於通信的固定格式,但是它允許傳輸任意的 Web 頁面。其它互聯網上的類似協議是 XMPP,即時消息的常用協議,以及 FTP,用於在客戶端和服務器之間下載和上傳文件的協議。