1. 程式人生 > >倉庫規模作業系統的背景之作業系統

倉庫規模作業系統的背景之作業系統

目錄

前言

作業系統

經典分散式作業系統

資料中心作業系統

問題和挑戰

效率

安全

觀察

新抽象的可行性

總結


前言

本文是Malte Schwarzkopf的博士論文《Operating system support for warehouse-scale computing》一個翻譯版本,融入了作者自身的經驗和理解,讀者如果想閱讀原文,可以訪問:http://people.csail.mit.edu/malte/pub/dissertations/phd-final.pdf

編寫本文的目的是提供一箇中文版本的文件,同時為自己保留一份學習筆記,供日後事件參考以及優化調整。當然,優化調整部分不能更新在公網,因為筆者同一時間在公司內網釋出了改文章,相應部分只會更新在公司內網的文章中。

作業系統

前面章節中的例子說明了典型的大型資料中心的工作負載,同時它們的細節不同,所有分散式應用程式都依賴於本地的和分散式的底層系統軟體。在這一節中,我考慮在資料中心作業系統的性質和作用。作業系統提供硬體抽象,多程序,資源共享以及程式和使用者之間的安全隔離。這種作業系統概念在六十年的過程中進化,主要驅動力就是資源共享效率。

起源:早期的機器只相當於原始的引導載入程式,例如“某個特定的載入程式”。 在圖靈的自動化計算引擎ACE上的一種不變的初始次序,或者在EDSAC上硬連線的初始化命令。很快大家都意識到,由系統軟體執行多個使用者程式對於高效的使用機器是至關重要的。

因此,設計了監視器(或監控器)程式自動按順序執行多個作業(“批處理”)。這樣的批處理監視器開啟了多道程式設計(multiprogramming

),但沒有支援互動系統的使用。機器的時間共享能夠使用多個程式共享處理器看似並行執行,但是需要一種機制來中斷當前計算並跳轉到監督器中。早期共享系統,如CTSS和Titan監控器,作為一個批量監控器和互動式作業系統的組合:遠端終端互動式的訪問計算機,但處理器在空閒時才執行傳統的批處理作業。這有點類似於資料中心批處理和服務之間的資源共享,其目的是回收服務的空閒資源嘗試性用於批處理作業。這裡需要注意的是,當批處理作業執行過程中被優先順序更高的服務或者批處理中斷時,可以選擇“暫停”或者“結束”作業,這要視情況而定。筆者以前設計的視訊/影象高效能運算平臺選擇的就是結束,因為這種方案實現比較簡單,受限於現場環境沒有比較好的“暫停”方案,利用資源空閒期賭博性的執行批處理作業,萬一成了呢!

時間共享產生了許多在今天的操作中使用的保護和隔離機制:段、虛擬記憶體、保護環(protection ring)和一個具有ACL的單個檔案系統名稱空間。然而,所有這些抽象專注於在多個程式和使用者之間安全地共享一臺機器。後面,我解釋如何分佈在多臺機器上。

經典分散式作業系統

早期的計算只限於一臺帶有遠端終端的通用機器。然而,跨機器的分散式操作的研究早在20世紀60年代中期,當Fuchel和Heller在兩個資料中心6600臺機器之間共享一個擴充套件的核心儲存(extended core store ECS)。他們的“基於ECS的作業系統” 通過把資料交換到ECS使程序在機器之間遷移成為可能,並且引入了緩衝的I/O和容差故障。其實這一點比較好理解,就好像現在的虛擬機器關機後再把虛擬機器檔案拷貝到另一個主機上啟動就可以復原,當然程序遷移要比虛擬機器遷移要輕量一些。

然而,直到20世紀70年代末,當小型機和個人工作站的成本、穩定性變得可以接受,同時出現相對廉價的區域網技術,幾乎沒有一家機構執行多臺計算機。當第一次可能擁有大量連線的計算機時,資源池的概念觸發分佈作業系統的發展(見表2.5)。

2.5:典型的分散式作業系統及其屬性。

早期分散式作業系統:HYDRA的C.mmp機是其中之一最早的分散式作業系統。C.mmp由十六個具有共享時鐘和共享儲存的PDP11機器組成,通過交叉連線。儘管它相當像C.mmp的對稱多處理(Symmetrical Multi-Processing SMP)架構,HYDRA開創了分散式作業系統幾個關鍵的原理,比如使用分散式物件作為主要抽象,容忍機器和連線故障,以及基於能力(capability-based )的保護。

Medusa,CMU早期的另一個分散式作業系統,目標是Cm*架構,以10為簇連線50個“計算模組”。由於在模組之間通訊成本高,Medusa強調了區域性性和限制性共享。Medusa是以顯式訊息傳遞為中心的分散式作業系統的先例之一,並抽象三類物件暴露給使用者,包括(i)頁、(ii)管道和訊號量,和(iii)檔案、“特別工作組(task forces)”和描述符列表。由於硬體的限制,Medusa只提供了適度和粗粒度的保護:通過描述符訪問物件,這些描述符駐留在受保護的描述符列表中 。關於特別工作組原文是task forces,我的理解是具備較高許可權的一些程序/執行緒之類的東東。

訊息傳遞系統:Rochester Intelligent Gateway(RIG)的Aleph OS、Acdent和Mach是80年代初開發的三個分散式作業系統,他們都是基於利用埠的訊息傳遞(程序訊息佇列)。

Aleph的設計很簡單:埠不受保護,全域性識別符號被當作資料對待,訊息傳遞不是完全透明的,即使用者必須瞭解訊息接收者的定位(這句話筆者也不太理解想,所以也找不到好的翻譯詞語)。它的使用場景是提供小型計算機網路,並充當大型、分時複用機器的“閘道器。

Accent重新設計RIG的原理,圍繞虛擬記憶體、完全透明和一個物件風格程式設計模型。Accent有一個磁碟上的“頁面儲存”用於持久儲存,核心將頁面載入到記憶體中以響應訊息。為了優化較大訊息傳輸,Accent使用copy-on-write重新對映到主機地址空間,跨機器邊界通訊息過懶檢索(我的理解是需要時在檢索)遠端儲存來實現。Accent程式設計人員使用介面描述語言IDL編譯器生成的高階的過程呼叫介面,類似的IDL概念存在於後來許多的分散式和微核心作業系統中,以及在今天的資料中心RPC庫中,例如Protocol Buffer。

Mach使用了Accon的原理,並擴充套件它們支援多處理器和相容Unix。它引入了執行緒,允許共享任務的(程序的)埠,可以使用者空間共享記憶體做同步,並支援外部使用者空間頁。Mach作為一個微核心架構具有影響力,但作為一個分散式作業系統,它因為全透明的訊息抽象的通訊成本比計算昂貴得多而最終受到阻礙。

其他分散式作業系統提供了更接近傳統系統呼叫API的介面。例如,LOCUS和VAXCluster在VAX機器上建立分散式系統,擴充套件VAX/VMS和Unix範例用於支援分散式。LOCUS在共享儲存的副本檔案上支援巢狀事務,每個副本所在本地作業系統強制執行互斥。LOCUS通過分散式命名目錄定位檔案,對它們的訪問是完全透明的。還有,LOCUS支援的動態叢集節點,並在網路分割槽依然保持可用,在修復時使用協調協議合併分歧狀態。相比之下,VASCluster組合了一些VAX機器和專用儲存節點成為單個安全域。決定是由節點投票產生的,出現分割槽時,少數節點分割槽不可用。不像LUCUS,分散式儲存中的檔案操作依賴於分散式鎖管理器。

基於RPC的系統:20世紀80年代後期,出現了幾個大型分散式作業系統專案,例如V、Sprite和Amoeba,它們使用遠端過程呼叫(RPC)模型,沒有直接暴露訊息格式。然而,他們的方法不同:Sprite和V目標是每個使用者工作站(per-user workstation)模型,使用程序遷移來利用空閒資源。Sprite基於共享檔案系統(類似LOCUS),強調了Unix的相容性(比如Mach),並且沒有開放支援分散式應用程式的特殊特性。相比之下,Amoeba假設所有使用者共享基於分散式物件和能力(如Chorus)的集中處理池。它有一個微核心體系結構,具有系統範圍使用者空間的服務和完透明的遠端操作。

Plan9Plan9是在20世紀90年代初作為UNIX的概念繼承者開發的。對於透明的分散式操有更普遍的檔案抽象和核心級支援。Plan9目標是網路終端使用者的工作站,並提倡以檔案為中心,允許遠端資源掛載到每個程序名稱空間。因此,通過名稱空間掛載,本地應用程式可以透明地與遠端程序、裝置和其他資源互動。

Plan9從未被廣泛採用,但它的一些關鍵概念隨後出現在作業系統:Linux中目錄結構的procfs是一個以暴露檔案的方式控制鉤子的例子;容器使用的核心名稱空間是每個程序一個名稱空間的例子;和基於JSON的REST API類似於Plan9的文字訊息傳遞。

為什麼分散式作業系統不能被採納?分散式作業系統開發超過了30年,當時他們的特徵很少出現在現代作業系統中。我相信分散式作業系統未能廣泛採用的原因有三:

  1. 沒需求.20世紀80年代的工作負載很少需要多臺機器的資源,複雜的分散式操作很難讓他們體現價值。經典的分散式作業系統是可行的技術,但是沒有任何迫切的使用場景。
  2. 單機效能增益戰勝了平行計算。原則上可以利用並行性提高效能的工作負載通常在大型、昂貴、分時複用的機器上執行也很好。對於桌面工作負載而言,平行計算很難獲得收益,因為更快的工作站很快就可用了。
  3. 計算和網路速度之間的差異更有利於本地計算。儘管隨著網路技術的不斷完善,本地計算速度仍然大大超過了跨機的通訊速度。事實上,這個差距在80年代末擴大了:時鐘速度迅速增加,但網路延遲僅緩慢地降低,使得遠端訊息傳輸變得越來越昂貴。

然而,在現代資料中心的環境下,所有這些條件都發生了重大變化:

  1. 工作負荷已經需要分散式。資料中心工作負載從根本上需要分散式規模的擴容和容錯能力,以及面對大量機器分散式是必要性而非可選。
  2. 單機效能提升放緩。工作負載不再依賴機器變得越來越快。此外,基於請求和資料並行的工作負載需要超過單個機器資源的網路和儲存頻寬。
  3. 網路效能相對於計算速度增加。20世紀80年代計算速度超越網路速度的趨勢在90年代開始逆轉:網路頻寬仍然增加並且接近DRAM頻寬,並且網路延遲再次降低。

因此,資料中心運營商已經開發了分散式基礎設施系統滿足這些需要。在下一節中,我將在概念上的“資料中心作業系統”中討論他們的作用。

資料中心作業系統

在倉庫規模的資料中心中看到的工作負載需要跨機器協作、資源管理、資料共享和身份驗證。專用分散式基礎設施系統服務於更上層的使用者應用程式。使用者應用程式依賴於分散式基礎設施系統,就像傳統應用程式依賴於本地作業系統一樣:它們假設分散式基礎設施服務總是可用的,並且依賴它們實現關鍵功能(例如,持久儲存)。因此,分散式基礎設施系統充當資料中心作業系統。

表2.6列出了傳統單機作業系統功能的分散式基礎設施等價物。例如,叢集管理器在啟動、排程和終止任務時形成特權核心的分散式等價物。叢集管理器還執行准入控制,並在不同的任務之間劃分硬體資源(另一個傳統的核心職責)。同樣,分層分散式檔案系統是傳統本地和網路檔案系統的可伸縮等價物,旨在公開類似的儲存抽象。

表2.6:許多經典的本地作業系統元件在當前的分散式基礎設施系統中具有等價物,它們構成了事實上的資料中心作業系統。

然而,這個列表僅僅有點粗略的近似。一些分散式基礎設施沒有直接的本地作業系統等價物:非結構化儲存系統,如blob儲存和鍵值儲存,最多可以視為繞過核心檔案系統或在其上構建的資料庫後端的等價物。

在其他情況下,類比更加微弱:例如,並行資料處理系統在某些方面是多執行緒庫的分散式等價物,但是通常具有更高層次的程式設計模型和內建的容錯機制。同樣,用於分散式鎖定、資源和服務發現的協調服務在傳統作業系統中也有類似的前輩(例如,UNIX/etc檔案系統和Windows登錄檔),但是協調服務必須使用Paxos或Raft等演算法來實現分散式一致性,以便在多個機器之間提供一致檢視。可以這麼理解:單機的多個服務一般採用檔案系統/登錄檔等實現全域性配置,但是對於分散式系統來說,全域性的配置也是通過每個單機的檔案系統/登錄檔實現,但是要通過一致性演算法實現每個單機的檔案系統/登錄檔的內容一致。當然了,我們肯定不能直接訪問協調服務的檔案系統,而是訪問協調服務提供的介面,這樣解釋是為了方便理解。

鑑於這些相似之處,人們可能會想知道為什麼這些系統不是從經典的分散式作業系統抽象的基礎之上建立,開發人員之所以設計自己的抽象並從頭構建新系統,有兩個原因:

  1. 靈活性:資料中心棧通常有幾個專用的系統,例如Facebook棧中不同的快取系統。這些系統不是眾所周知的長期用例發展而來,而是為了響應緊急的業務需求。從零開始構建系統可以快速演進,獨立於更新很慢的廣泛使用的標準、通用抽象或作業系統擴充套件。
  2. 不可用性:經典分散式作業系統未來不再被使用,它們的抽象在當前的作業系統中不存在或者沒有被採用。因此,沒有廣泛部署的用於構建分散式系統的抽象可用。

資料中心作業系統的這種演進產生了一系列系統,這些系統對於它們的特定用例和部署工作得很好。然而,這並不是沒有它的缺點,導致幾個問題和挑戰,我接下來將討論。

問題和挑戰

與單機作業系統和經典的分散式作業系統不同,組成資料中心作業系統的基礎設施服務集合實際上在某種程度是點對點的,並且分散式作業系統元件缺乏統一性和可組合性。

表2.7通過比較當前資料中心基礎設施軟體和經典的分散式作業系統來說明這一點。在高層上,顯然,經典的分散式作業系統在抽象上力求統一,期望它們被各種各樣的應用程式使用。

表2.7:當前用在“資料中心作業系統”的分散式基礎設施系統和經典分散式作業系統的比較。

然而,資料中心作業系統中的每個系統都有自己的方法、API和抽象。接下來,我將討論這種差異對資料中心基礎設施的效率和安全性的影響。

效率

不同的分散式基礎設施元件使用並公開它們儲存和處理的資料的表示:例如,考慮HDFS檔案vs Spark RDD vs BigTable的三維對映中的值。所有這些都包含任意的二進位制資料,但是不復制資料就不可能從一個表示轉換為另一個表示。

這不僅導致不必要的拷貝,而且使不同系統之間的資料共享複雜化:不存在共享只讀記憶體對映的分散式等價物,例如,在Web伺服器、分散式檔案系統和分析作業之間共享的一組圖片。實際上,由於這個原因,資料中心基礎設施最終得到了多個、不協調和衝突的資料快取實現:本地機器作業系統緩衝區快取、memcached之類的鍵值儲存以及Tachyon之類的檔案系統快取覆蓋。

現有的分散式系統的抽象也常常缺乏對內省(計算機程式在執行時檢查物件型別的一種能力,通常也可以稱作執行時型別檢查)的支援。如果不知道特定於系統的API細節,則很難或不可能找到資料的位置、它們的永續性或它們副本的位置。然而,這些資訊對於跨系統優化可能是至關重要的。例如,從快取在另一臺機器記憶體上的資料集讀取比從本地磁碟讀取更有效,但是寫入可能需要在不同的故障域中進行復制。

最後,大多數當前資料中心管理資源的基礎設施系統都有一箇中心化控制器:例如Borg中的BorgMaster、HDFS中的NameNode和Spark中的Spark master。“高可用”是通過控制器的多副本實現的,不以分散式方式管理資源及其元資料。

因此,資料中心作業系統的效率取決於具有更加統一、支援內省和分散式的資源管理抽象。實際上,未來的資料中心硬體趨勢——例如RDM的預期廣泛部署——只會加劇這種需求。

安全

命名還與資源存在的可否認性密切相關:如果使用者在鍵值儲存中獲得資料項的鍵,那麼他們可以認為它存在。大多數現有系統沒有名稱空間,因此不能劃分資源發現(比如只能看到自己所在名稱空間的資源)或選擇性否認絕資源存在(即使資源存在但是也看不到),無論它們是基於能力許可權的還是基於ACL的。例如,memcached名稱空間必須使用鍵字首或字尾實現,並且HDFS目錄列舉只能通過UNIX檔案系統許可權表達拒絕。

當前的訪問控制方案不僅過於粗粒度,而且缺乏一致性:每個系統有它們自己主體(例如,HDFS中的使用者/組、Mesos中的使用者和框架工程)、身份驗證方法和限制屬性的自定義概念。由於每個系統都從頭開始實現訪問控制,而且常常不完整,因此多個使用者訪問同一資料中心作業系統的元件的端到端安全性和隔離性通常很差。

最後,資料中心運維人員需要審計資源訪問,不幸的是,當前系統要麼根本不支援審計,要麼僅僅支援定製的審計日誌(例如,在HDFS中)。

經典的分散式作業系統通過依賴能力保護解決了許多這些問題,主要有兩個原因。首先,雖然ACL和許可權都可以被分散式管理,但是由於它們不需要使用ACL和能力對主體進行身份驗證,所以它們適合分散式使用。第二,能力許可權很好地對映到分散式系統中常見的資料流抽象。它們傳統的缺點——複雜的程式設計模型和撤銷的困難——在完全分散式的環境中影響不大。

顯然,當前資料中心基礎設施將受益於使用統一方法實現的更細粒度的保護和訪問控制。因此,在資料中心環境中,良好的安全性和細粒度保護需要基於廣泛的、細粒度的能力訪問控制。

觀察

對當前充當作業系統的資料中心繫統軟體的調查表明,有很大的改進潛力。確實,其他人也提出了類似的觀點,並呼籲在資料中心作業系統中採用更統一、可重用和可組合的抽象和機制。

我的主要觀點是,經典的分散式作業系統已經解決了上述許多問題——儘管是在稍微不同的上下文中——因此,我們可以並且應該向他們學習。因此,我們可能能夠識別新的通用分散式作業系統抽象,這些抽象為當前的資料中心作業系統元件提供更加統一、有效和安全的資源管理和訪問控制。

下一節將研究我們是否可能希望僅通過少量的抽象來支援現有資料中心應用的需求。

新抽象的可行性

對於一個數據中心作業系統來說,新的資源管理和訪問控制抽象的概念必然會引起復雜性的問題:需要多少這樣的抽象來支援通用應用程式,我們能夠讓應用程式來僅使用新的抽象嗎?後者從安全性角度來看很有趣:只使用新抽象的應用程式不可能繞過它們的訪問控制機制。

關鍵問題是,一小組操作是否足以有效地支援資料中心應用程式——或者甚至僅僅支援效能敏感的“資料平面”。如果是這樣,那麼資料中心作業系統的清潔模型似乎是可行的。下面,我提出一個探索性的研究,提供了對這個問題的一些見解。

實驗:我使用Linux系統呼叫作為典型資料中心應用程式呼叫的作業系統功能的(原始)代理,我研究了四個應用程式:Hadoop MapReduce、Redis鍵值儲存、Zookeeper協調服務和GraphChi圖形計算框架。使用典型的工作負載對每個應用程式進行基準測試,並使用strace監視其系統呼叫呼叫。當然,這無法捕獲所呼叫的高階分散式操作,但是它給出了一個指示,表明一個乾淨的模型必須提供最小的本地作業系統功能。

圖2.8:公共資料中心應用程式上的探索性系統呼叫跟蹤的結果。

圖2.8a比較了不同應用程式呼叫的不同Linux系統呼叫的總數。對於Hadoop,我測量了典型Hadoop叢集的四個不同的系統元件:(i)MapReduce JobTracker(“Hadoop-JT”),(ii)MapReduce TaskTracker(“Hadoop-TT”),(iii)HDFS NameNode(“Hadoop-NN”),(iv)HDFS DataNode(“Hadoop-DN”)。

在Java虛擬機器(JVM)上執行的Hadoop使用最大數量的85個不同的系統呼叫;然而,同樣基於Java的ZooKeeper只使用28個,而基於C/C++的Redis和GraphChi分別使用19個和20個不同的系統呼叫。這表明作業系統功能的使用範圍主要並不取決於編譯器或執行時,而是以資料為中心的應用程式的固有屬性。如果只考慮通常呼叫的系統呼叫,則系統呼叫數量將進一步收縮,所謂常用系統呼叫要麼(i)佔所有呼叫數量的1%以上,要麼(ii)在每個應用程式級請求(即“資料平面”)上至少發生一次。實際上,除了Hadoop之外,所有應用程式都有五個或更少的“公共”系統呼叫(圖2.8a)。

在圖2.8b中,我按類別對系統呼叫進行分組。可能毫不奇怪,主要的類別是I/O、同步和資源管理,其中I/O系統呼叫占主導地位,正如我們在分散式、資料密集型應用程式中所期望的那樣。

圖2.8c顯示了每個系統呼叫的相對頻率,它們佔總呼叫的1%以上。系統呼叫呼叫總數的35-50%是read(2)或write(2);接下來最頻繁的呼叫是與Linux的futex(“fast user-space mutex”)同步機制相關的那些。總而言之,總共有11個系統呼叫覆蓋了所進行的呼叫的99%。這是326個Linux系統呼叫的一個小子集,表明在這些資料中心應用程式的“資料平面”上不需要Linux系統呼叫API的全量。

觀察:雖然這些結果暗示許多資料中心應用程式只使用一小組本地作業系統抽象,但是應該謹慎。Linux中提供的許多額外系統呼叫僅用於向後相容,很少使用,而其他系統呼叫可能僅用於很少觸發的程式碼路徑(例如,用於錯誤處理),甚至像ioctl(2)和fnctl(2)這樣的其他系統呼叫都具有高度過載的語義。我的理解是,像ioctl(2)這樣的系統呼叫可以被很多種裝置實現,同時每種裝置還有不同的請求命令,看上去都是相同的系統呼叫,背後的意義卻大不相同。

然而,這些結果是令人鼓舞的:他們建議構建一個新的分散式資料中心作業系統是可行的,其抽象足以支撐通用的分散式應用程式。這具有雙重優點:(i) 評估建立在新抽象之上乾淨的“資料平面” 的效能變成可能,(ii)撤銷對遺留作業系統設施的訪問,防止潛在的安全漏洞和旁路 (例如,通過pipe(2))。

總結

在本節中,我解釋了作業系統的發展是如何通過共享底層硬體來尋求更高資源利用率的。我調查了二十世紀八十年代的經典分散式作業系統,它們沒有得到採用,可能是因為它們的設計超前當時的工作負載。

然後,我發現現代資料中心事實上已經由當今使用的多個分散式基礎設施系統組成了分散式作業系統。然而,這種方法有幾個缺點,並且面臨效率和安全挑戰:

  1. 我發現分散式基礎設施系統缺乏經典分散式作業系統的統一抽象。
  2. 因此,資料中心作業系統的效率總體上受到損害:資料跨系統表示必須複製和轉換、共享需要副本,並且系統利用新的硬體範例並不容易。
  3. 缺乏單個訪問控制方案降低了資料中心作業系統的端到端安全性:系統有自己的身份驗證概念,使用可變粒度的訪問控制原語,並且通常不可能進行選擇性委託。

因此,在資料中心OS上下文中考慮來自經典分散式作業系統的想法似乎很有用。的確,我藉助於一項探索性的研究論證,資料中心應用的狹隘和統一的需求使得設計一套新的分散式作業系統抽象是可行的,它完全支援這種應用的“資料平面”(2.2.4)。

在下一節中,我將研究資料中心OS的特定部分:叢集管理器的排程器,它決定將兩個應用程式任務放在共享叢集基礎結構中的何處。