執行緒與行程可視為「同時做更多事」的手段:它們讓程式(的片段)看起來像在同時執行。在單處理器電腦上,這種同時執行當然是假象——CPU 只有一顆,同一時間只執行一條執行緒或行程的一道指令,靠快速切換製造出平行的錯覺。

這種「實際只有一顆 CPU、卻能假裝有很多顆」的分離手法可以推廣到其他資源,也就是資源虛擬化(resource virtualization)。虛擬化已應用數十年,但隨著(分散式)電腦系統日益普及與複雜、應用軟體幾乎總是比其底層的系統軟體與硬體活得更久,它重新受到關注。

虛擬化在分散式系統中的角色#

實務上,每個(分散式)電腦系統都對上層軟體提供程式介面——從 CPU 的基本指令集,到現代中介軟體隨附的大量 API,種類繁多。虛擬化的本質就是擴充或替換既有介面,去模仿另一個系統的行為:在系統 B 之上模擬出系統 A 的介面,讓為 A 寫的程式跑在 B 上。

圖 3-5:(a) 程式、介面與系統之間的一般組織;(b) 在系統 B 之上虛擬化系統 A 的一般組織

虛擬化在 1970 年代被引入的最重要理由之一,是讓老舊軟體(legacy software)能跑在昂貴的大型主機上——這些軟體不只包括各式應用程式,實際上還包括它們當初賴以開發的作業系統。IBM 370 大型主機(及其後繼者)成功應用了這個做法:提供一個虛擬機器,讓不同的作業系統移植上去。隨著硬體變便宜、電腦更強大、作業系統種類減少,虛擬化一度式微;但 1990 年代末以來情勢再度轉變:

  • 軟硬體演化速度不對等:硬體與低階系統軟體變動相當快,較高抽象層的軟體(如中介軟體與應用程式)則穩定得多——老舊軟體跟不上其所依賴平台的演進步調。虛擬化能把舊介面移植到新平台,立刻讓大量既有程式用上新平台。
  • 網路無所不在:現代電腦幾乎必然連網,系統管理者因此得維護一大批異質的伺服器,各自跑著非常不同的應用、供客戶端存取,同時各種資源又得讓這些應用容易取用。虛擬化能大幅減少平台與機器的多樣性:讓每個應用跑在自己的虛擬機器上(可能連同相關函式庫與作業系統),再讓這些虛擬機器跑在共同平台上。

這種「連同環境一起虛擬化」的做法帶來高度的可攜性與彈性。例如 Awadallah 與 Rosenblum(2002)主張:若邊緣伺服器支援虛擬化,讓完整站台連同其環境可被動態複製,要實現能輕鬆支援動態內容複製的內容遞送網路(content delivery network),管理會容易得多。對分散式系統而言,正是這類可攜性論點使虛擬化成為重要機制。

虛擬機器的架構#

虛擬化在實務上有許多實現方式(Smith 與 Nair(2005)有完整綜覽)。要理解其差異,先要認識電腦系統一般在四個層次提供四種介面:

  1. 硬體與軟體之間、由任何程式皆可呼叫的機器指令構成的介面。
  2. 硬體與軟體之間、僅供特權程式(如作業系統)呼叫的機器指令構成的介面。
  3. 作業系統提供的系統呼叫介面。
  4. 函式庫呼叫構成的介面,一般即所謂的應用程式介面(application programming interface, API);許多情況下系統呼叫被 API 隱藏起來。

圖 3-6:電腦系統所提供的各種介面

虛擬化的本質就是模仿這些介面的行為,做法有兩大類:

  • 行程虛擬機器(process virtual machine):建立一個執行期系統,提供一套抽象指令集作為執行應用程式之用。指令可以用直譯的(如 Java 執行環境),也可以用模擬的(如在 UNIX 平台上跑 Windows 應用程式——後者連系統呼叫的行為也得模仿,實務證明通常遠非易事)。此名稱強調虛擬化只針對單一行程。
  • 虛擬機器監視器(virtual machine monitor, VMM):提供一個完全遮蔽原始硬體的系統層,但對外提供同樣(或其他)硬體的完整指令集作為介面。關鍵在於這個介面可同時提供給不同的程式使用,因此同一平台上可以有多個不同的作業系統獨立並行地執行。典型例子是 VMware(Sugerman 等人,2001)與 Xen(Barham 等人,2003)。

圖 3-7:(a) 行程虛擬機器,含多組(應用程式、執行期系統)組合的實例;(b) 虛擬機器監視器,含多組(應用程式、作業系統)組合的實例

如 Rosenblum 與 Garfinkel(2005)所論,VMM 在(分散式)系統的可靠性與安全性方面將日益重要:由於它能隔離完整的應用程式及其環境,錯誤或安全攻擊造成的失效不再波及整台機器;同時 VMM 讓硬體與軟體進一步解耦,可把完整環境從一台機器搬到另一台,大幅提升可攜性。