在討論分散式系統的原理之前,先看看有哪些類型的分散式系統。以下區分三大類:分散式計算系統(distributed computing systems)、分散式資訊系統(distributed information systems)與分散式普及系統(distributed pervasive systems)。
分散式計算系統#
這一類用於高效能運算,粗略可分為兩個子群:
- 叢集計算(cluster computing):底層硬體是一批相似的工作站或 PC,透過高速區域網路緊密相連,且每個節點跑相同的作業系統。
- 網格計算(grid computing):通常是多個電腦系統的聯邦(federation),各系統可能隸屬不同的行政網域,在硬體、軟體與網路技術上也可能差異極大。
叢集計算系統#
當個人電腦與工作站的性價比大幅改善後,用現成(off-the-shelf)技術把一批簡單電腦接上高速網路來組一台「超級電腦」,在財務與技術上都變得吸引人。叢集計算幾乎都用於平行程式設計:讓單一(計算密集的)程式在多台機器上平行執行。
以知名的 Linux 架構 Beowulf 叢集為例(圖 1-6 的一般組態):
- 每個叢集由一批**計算節點(compute node)組成,統一由單一主節點(master node)**控制與存取。
- 主節點負責把節點分配給特定平行程式、維護已提交工作的批次佇列,並提供系統的使用者介面——換言之,主節點跑的正是執行程式與管理叢集所需的中介軟體,計算節點則往往只需要標準作業系統。
- 中介軟體的重要組成是執行平行程式的函式庫。如第 4 章將討論的,這些函式庫多半只提供進階的訊息式通訊功能,並不處理故障行程、安全性等問題。

圖 1-6:叢集計算系統的一個例子。
與上述階層式組織相對,MOSIX 系統(Amar et al., 2004)採取對稱式做法:試圖提供叢集的單一系統映像(single-system image)——對行程而言,叢集看起來就是一台電腦,達到極致的分散透明性。(如前所述,在所有情況下都維持這種映像是不可能的。)MOSIX 的高透明性來自允許行程在叢集節點間動態、可搶佔地遷移:使用者可在任一節點(稱為 home node)啟動應用程式,之後行程可透明地移往其他節點,例如為了更有效利用資源。行程遷移詳見第 3 章。
網格計算系統#
叢集計算的特徵是同質性:叢集內的電腦大多相同、作業系統相同、接在同一網路上。相對地,網格計算系統具有高度異質性:對硬體、作業系統、網路、行政網域、安全政策等一概不做假設。
網格計算的關鍵議題是把不同組織的資源匯集起來,讓一群人或機構得以協作。這種協作以**虛擬組織(virtual organization)**的形式實現:
- 屬於同一虛擬組織的人,對提供給該組織的資源擁有存取權。
- 資源通常包括計算伺服器(含超級電腦,可能以叢集實作)、儲存設施與資料庫,也可以包括望遠鏡、感測器等特殊網路裝置。
由於這種性質,網格計算的軟體多半圍繞著「讓特定虛擬組織的使用者與應用程式存取來自不同行政網域的資源」展開,因此常聚焦於架構議題。Foster et al.(2001)提出的分層架構包含四層:
- fabric 層(fabric layer):提供特定站點本地資源的介面。這些介面為虛擬組織內的資源共享量身打造,通常提供查詢資源狀態與能力的功能,以及實際的資源管理功能(例如鎖定資源)。
- 連結層(connectivity layer):支撐跨多個資源的網格交易(grid transaction)所需的通訊協定,例如在資源間傳輸資料、從遠端存取資源;也包含驗證使用者與資源的安全協定。值得注意的是,許多情況下被驗證的不是人類使用者本身,而是代表使用者行動的程式——因此「把權利從使用者委派(delegate)給程式」是連結層必須支援的重要功能(討論安全時將深入回顧委派)。
- 資源層(resource layer):負責管理單一資源。它利用連結層提供的功能,並直接呼叫 fabric 層開放的介面,例如取得特定資源的組態資訊,或執行建立行程、讀取資料等操作。資源層因此負責存取控制,並依賴連結層完成的驗證。
- 集體層(collective layer):處理對多個資源的存取,通常包含資源探索、把任務配置與排程到多個資源上、資料複製等服務。與連結層和資源層那組相對少量的標準協定不同,集體層可能包含許多針對不同目的的協定,反映它能提供給虛擬組織的服務光譜之廣。
- 應用層(application layer):在虛擬組織內運作、使用網格計算環境的應用程式。

圖 1-7:網格計算系統的分層架構。
集體層、連結層與資源層合起來構成所謂的網格中介軟體層(grid middleware layer),共同提供對可能散布在多個站點的資源之存取與管理。從中介軟體觀點看,網格計算裡「站點(行政單位)」的概念很普遍;這一點隨著逐漸轉向服務導向架構(service-oriented architecture)——各站點透過一組 Web services 開放各層的存取(Joseph et al., 2004)——而更加明顯,並催生了另一套架構定義:開放網格服務架構(Open Grid Services Architecture, OGSA)。OGSA 層次與元件眾多、相當複雜——複雜似乎是所有標準化過程的宿命。細節見 Foster et al.(2005)。
分散式資訊系統#
另一大類分散式系統出現在那些擁有大量網路化應用程式、卻苦於互通性的組織。許多既有的中介軟體解決方案,正是為了讓應用程式更容易整合進企業級資訊系統而生(Bernstein, 1996; Alonso et al., 2004)。
整合發生在幾個層次:
- 最低層次:一個網路化應用就是一台跑該應用(常含資料庫)的伺服器,供遠端客戶端程式使用——客戶端送請求、伺服器回應。此層次的整合是讓客戶端把多個請求(可能給不同伺服器)包成一個分散式交易(distributed transaction)執行,關鍵想法是這些請求全部執行或全部不執行。
- 隨著應用日益精緻、逐漸拆分為獨立元件(特別是資料庫元件與處理元件分離),整合也需要讓應用程式彼此直接通訊——這催生了龐大的**企業應用整合(Enterprise Application Integration, EAI)**產業。
交易處理系統#
以資料庫應用為例,實務上對資料庫的操作通常包在**交易(transaction)**裡。交易式程式設計需要特殊的原語(primitive),由底層分散式系統或語言執行環境提供,典型如:BEGIN_TRANSACTION、END_TRANSACTION、READ、WRITE。確切的原語清單取決於交易中操作的物件種類(Gray and Reuter, 1993)——郵件系統可能有寄信、收信、轉寄的原語,會計系統則大不相同。交易內也允許一般敘述、程序呼叫等;特別地,遠端程序呼叫(Remote Procedure Call, RPC)也常被封裝進交易,形成所謂交易式 RPC(transactional RPC)(RPC 詳見第 4 章)。

圖 1-8:交易的原語(primitive)範例。
BEGIN_TRANSACTION 與 END_TRANSACTION 界定交易的範圍,其間的操作構成交易的主體:要嘛全部執行,要嘛全都不執行。
交易的四個特徵性質,常以首字母合稱 ACID:
- 原子性(Atomic):對外界而言,交易的發生是不可分割的。交易進行中,其他行程(無論是否也在交易中)看不到任何中間狀態;交易要嘛完整發生,要嘛完全沒發生,且發生時是單一、不可分割的瞬時動作。
- 一致性(Consistent):交易不違反系統不變量(invariant)。例如銀行系統的關鍵不變量是「金錢守恆」:每次內部轉帳後,銀行的總金額必須與轉帳前相同。交易期間不變量可以短暫被打破,但這種違反在交易之外不可見。
- 隔離性(Isolated):又稱可序列化(serializable)。多個交易同時執行時,對每個交易以及其他行程而言,最終結果看起來就像所有交易按某個(依系統而定的)順序依序執行。
- 持久性(Durable):交易一旦提交(commit),無論發生什麼,結果都是永久的;提交後的任何故障都不能撤銷或遺失結果。(持久性詳見第 8 章。)
到此為止的交易都定義在單一資料庫上。**巢狀交易(nested transaction)**則由多個子交易構成:頂層交易可以分岔出在不同機器上平行執行的子交易(為了效能或簡化程式設計),每個子交易又可以再執行或分岔出自己的子交易。

圖 1-9:巢狀交易。
子交易帶來一個微妙但重要的問題:假設某交易平行啟動了數個子交易,其中一個提交了,結果對父交易可見;父交易後續計算後卻中止(abort),整個系統要回復到頂層交易開始前的狀態——那個已提交的子交易的結果也必須被撤銷。也就是說,「提交即永久」只適用於頂層交易。
巢狀交易的語義是清楚的(雖然任意深度的巢狀需要可觀的管理工作):
- 任何交易或子交易開始時,概念上會拿到整個系統所有資料的私有副本,任其操作。
- 中止時,它的私有世界就消失,彷彿從未存在;提交時,它的私有世界取代父交易的世界。
- 因此若一個子交易提交後又啟動新的子交易,後者看得到前者的結果;反之,若外層交易中止,其下所有子交易也必須跟著中止。
巢狀交易對分散式系統很重要:它提供了把交易分散到多台機器的自然方式,並且依循原交易工作的邏輯切分——例如「規劃一趟需要訂三段航班的旅行」可以邏輯上拆成三個子交易,各自獨立管理。
在企業中介軟體的早期,處理分散式(或巢狀)交易的元件是伺服器/資料庫層級應用整合的核心,稱為交易處理監視器(transaction processing monitor, TP monitor)。其主要任務是提供交易式程式設計模型,讓一個應用程式能存取多個伺服器/資料庫。

圖 1-10:TP monitor 在分散式系統中扮演的角色。
企業應用整合#
應用程式與其資料庫愈是解耦,就愈需要獨立於資料庫的整合設施:應用元件之間應能直接通訊,而不只是交易處理系統支援的請求/回覆行為。這種應用程式間通訊的需求催生了多種通訊模型(本書後續詳談),主要想法是讓既有應用能直接交換資訊,而中介軟體是其中的通訊促成者:
- 遠端程序呼叫(RPC):應用元件透過一個本地程序呼叫向另一元件送出請求;請求被包裝成訊息送往被呼叫端,結果同樣以訊息送回、作為程序呼叫的回傳值。
- 遠端方法呼叫(Remote Method Invocation, RMI):隨物件技術流行而發展,本質上與 RPC 相同,只是操作對象是物件而非應用程式。
- 訊息導向中介軟體(Message-Oriented Middleware, MOM):RPC 與 RMI 的缺點是呼叫端與被呼叫端都必須同時在線,且必須確切知道如何指涉對方——這種緊耦合常被視為嚴重缺陷。在 MOM 中,應用程式只是把訊息送往邏輯聯絡點(常以主題 subject 描述);應用程式也可以宣告對某類訊息感興趣,由通訊中介軟體負責把訊息投遞給它們。這類發布/訂閱(publish/subscribe)系統是重要且持續擴張的一類分散式系統,第 13 章將深入討論。

圖 1-11:中介軟體作為企業應用整合中的通訊促成者。
分散式普及系統#
前面討論的分散式系統大多以穩定為特徵:節點固定、與網路有品質良好且近乎永久的連線。這種穩定性某種程度上是靠本書討論的各種追求分散透明性的技術實現的——例如豐富的失效遮蔽與復原技術讓人覺得「只是偶爾出點狀況」,隱藏節點實際網路位置的技術讓人以為節點不會移動。
行動與嵌入式運算裝置的出現讓情況大不相同:我們面對的是不穩定即預設行為的分散式系統,稱為分散式普及系統(distributed pervasive system)。這些裝置的典型特徵是體積小、電池供電、可移動、只靠無線連線——雖然並非所有裝置都具備全部特徵,這些特徵也未必是限制(現代智慧型手機的能力即為例證,Roussos et al., 2005)。
顧名思義,普及系統融入我們的環境之中(因此天生就是分散的)。一個重要特徵是普遍缺乏人為的管理控制:頂多由擁有者做些設定,裝置得自動探索環境、盡可能「安頓下來(nestle in)」。Grimm et al.(2004)把這種安頓精確化為普及應用的三個需求:
- 擁抱情境變化(embrace contextual changes):裝置必須持續意識到環境隨時可能改變。最簡單的變化是發現網路不再可用(例如使用者在基地台之間移動),應用程式應做出反應,例如自動連上另一個網路。
- 鼓勵臨機組合(encourage ad hoc composition):許多裝置會被不同使用者以非常不同的方式使用,因此裝置上執行的應用組合應容易設定——由使用者手動、或透過自動(但受控)的介入。
- 把共享視為預設(recognize sharing as the default):裝置加入系統通常就是為了取得(也可能提供)資訊,因此需要簡便地讀取、儲存、管理與共享資訊的手段;而在裝置連線斷續多變的情況下,可存取資訊所在的空間很可能隨時在變。
Mascolo et al.(2004)與 Niemela and Latvakoski(2004)得到類似結論:在移動性存在的前提下,裝置應支援簡便、依應用而異的本地環境調適,並能有效率地探索服務並做出反應。由此可見,分散透明性在普及系統中其實並不成立——資料、行程與控制的分散是這類系統的本質,與其遮掩,不如直接把分散暴露出來。
以下是普及系統的三個具體例子。
家庭系統#
圍繞家庭網路建立的普及系統日益流行,也可能是限制最少的一類。這類系統通常有一台以上的個人電腦,更重要的是把電視、音響視訊設備、遊戲機、(智慧型)手機、PDA 及其他個人穿戴裝置整合為單一系統,未來還可預期廚房家電、監視攝影機、時鐘、燈光控制器等也都會接進來。
從系統觀點看,有幾個挑戰必須先解決:
- 完全的自我設定與自我管理(self-configuring / self-managing):不能指望終端使用者有意願、有能力維護一個元件容易出錯的分散式家庭系統。**通用隨插即用(Universal Plug and Play, UPnP)**標準已完成不少工作——裝置能自動取得 IP 位址、彼此探索等(UPnP Forum, 2003)——但還不夠:例如裝置的軟體與韌體如何免人工介入地更新、更新後如何確保不破壞與其他裝置的相容性,仍不清楚。
- 管理「個人空間(personal space)」:家庭系統既有共享裝置也有個人裝置,資料也有共享限制。例如 Alice 的個人空間可能包含她的行事曆、家庭照片、日記、購買的音樂與影片等;這些個人資產的存放方式要讓 Alice 在適當時機都能存取,部分內容還要能(暫時)開放給他人——例如安排商務約會時。
延伸討論:儲存容量成長如何改變家庭系統架構
長期以來大家認為家庭系統的個人空間天生就分散在各裝置上,而這種分散容易導致嚴重的同步問題。不過硬碟容量快速上升、體積持續縮小,可能讓問題緩解:幫個人電腦配置數 TB 的儲存單元已不是問題,數百 GB 的可攜式硬碟也已裝進相當小的可攜式媒體播放器。照此趨勢,普及家庭系統可能採取這樣的架構:單一機器擔任主機(藏在地下室暖氣旁),其他固定裝置只提供便利的人機介面;個人裝置則塞滿日常所需的資訊,且永遠不會用完儲存空間。
然而儲存夠大並不解決個人空間的管理問題:能存下海量資料,問題就轉移成「存哪些相關資料、之後找得到」。我們將愈來愈常看到家庭網路這類普及系統配備推薦程式(recommender)——參考其他使用者存了什麼來辨識相近品味,進而推導該把哪些內容放進個人空間。有趣的是,推薦程式運作所需的資訊量往往小到可以在 PDA 上執行(Miller et al., 2004)。
電子健康照護系統#
另一類重要且新興的普及系統與(個人)電子健康照護有關。隨著醫療成本上升,新裝置被開發來監測個人健康狀況、必要時自動聯絡醫師;許多這類系統的主要目標是避免病人住院。
個人健康照護系統通常配備多種感測器,組織成(最好是無線的)體域網路(body-area network, BAN)。關鍵要求是這種網路最多只能極輕微地妨礙人的行動——網路必須在人移動時運作,不能有連到固定裝置的線。這導出兩種明顯的組織方式(圖 1-12):
- 本地集線器(hub):集線器是 BAN 的一部分,按需收集資料,並不時把資料卸載到較大的儲存裝置。優點是集線器同時可以管理 BAN。
- 持續無線連線:BAN 透過無線連線持續接上外部網路、即時送出監測資料;此時需要另外的技術來管理 BAN。當然,兩種方式都可再連上醫師或其他人。

圖 1-12:在普及式電子健康照護系統中監測一個人,使用 (a) 本地集線器或 (b) 持續的無線連線。
從分散式系統的觀點,我們立刻面對這些問題:
- 監測資料應存放在哪裡、如何存放?
- 如何防止關鍵資料遺失?
- 需要什麼基礎設施來產生與傳播警報?
- 醫師如何提供線上回饋?
- 如何讓監測系統達到極高的強健性?
- 有哪些安全議題?如何落實適當的政策?
與家庭系統不同,我們不能期待健康照護系統走向單一伺服器架構、讓監測裝置只保留最少功能。恰恰相反:基於效率,裝置與體域網路必須支援網內資料處理(in-network data processing)——例如監測資料得先聚合,再永久儲存或送交醫師。與分散式資訊系統不同,上述問題目前還沒有明確答案。
感測器網路#
最後一個例子是感測器網路(sensor network)。它常是普及運算的賦能技術之一,許多感測器網路的解法也重現在普及應用中。從分散式系統的觀點,感測器網路有趣之處在於它們幾乎都用於處理資訊——不只是提供通訊服務(那是傳統電腦網路的本行)。(網路觀點的綜述見 Akyildiz et al., 2002;較系統導向的介紹見 Zhao and Guibas, 2004。密切相關的還有網狀網路(mesh network):一批固定節點以無線鏈路通訊,可作為許多中型分散式系統的基礎,綜述見 Akyildiz et al., 2005。)
感測器網路的典型樣貌:
- 由數十到數百、數千個相對小的節點組成,每個節點配備一個感測裝置。
- 多數使用無線通訊,節點常靠電池供電。
- 資源有限、通訊能力受限、耗電受約束,效率因此必須高居設計準則之首。
把感測器網路視為分散式資料庫能清楚看出它與分散式系統的關聯——許多感測器網路部署於量測與監視應用(Bonnet et al., 2002),操作員想從(部分)網路提取資訊時,發出的查詢就像傳統資料庫查詢,例如「一號公路北向的車流量是多少?」答案很可能得由一號公路周邊的許多感測器協作提供,其他感測器則不受打擾。
把感測器網路組織成分散式資料庫,有兩個極端(圖 1-13):
- 只存在操作員端:感測器不合作,單純把資料送往操作員站點的集中式資料庫。缺點是感測器得把所有量測資料送過網路,浪費網路資源與能量。
- 只存在感測器端:把查詢轉發給相關感測器、由各感測器自行計算答案,操作員再設法聰明地聚合回傳的答案。缺點是浪費了感測器的聚合能力——善用的話,回傳給操作員的資料量可以少得多。

圖 1-13:組織感測器網路資料庫,資料的儲存與處理 (a) 只發生在操作員端,或 (b) 只發生在感測器端。
兩者都不理想,需要的是網內資料處理設施(與普及健康照護系統相同的結論)。一種明顯做法是沿著一棵涵蓋所有節點的樹轉發查詢,結果往樹根(查詢發起者所在)回傳時逐步聚合——聚合發生在樹的分支會合處。這個方案聽來簡單,卻引出困難的問題:
- 如何在感測器網路中(動態地)建立一棵有效率的樹?
- 結果的聚合如何進行?能否被控制?
- 網路鏈路失效時怎麼辦?
延伸案例:TinyDB 與發布/訂閱式的替代方案
這些問題在 TinyDB 中得到部分解答。TinyDB 為無線感測器網路實作了宣告式(資料庫)介面,本質上可搭配任何樹狀路由演算法:中間節點收集並聚合子節點的結果、連同自身的量測一起送往樹根。為求效率,查詢橫跨一段時間,讓操作可被謹慎排程,使網路資源與能量的消耗最佳化。細節見 Madden et al.(2005)。
然而當查詢可以從網路中不同位置發起時,TinyDB 這種單一樹根的樹可能不夠有效率。替代方案是在感測器網路中設置特殊節點,結果與相關查詢都轉發到那裡——簡單的例子:溫度讀數的查詢與結果收集在某處,濕度量測的則收集在另一處。這種做法直接對應發布/訂閱(publish/subscribe)系統的概念,第 13 章將深入討論。