《The Design of a Practical System for Fault-Tolerant Virtual Machines》論文研讀

BrianLeeLXT發表於2020-07-05

VM-FT 論文研讀

說明:本文為論文 《The Design of a Practical System for Fault-Tolerant Virtual Machines》 的個人理解,難免有理解不到位之處,歡迎交流與指正 。

論文地址VM-FT 論文

本文的總結包括論文內容以及 MIT6.824 Lec4 中的授課內容,其中包含了論文中沒有提及的一些細節 。


1. 前言

本論文主要介紹了一個用於提供 容錯虛擬機器 (fault-tolerant virtual machine) 的企業級商業系統,該系統包含了兩臺位於不同物理機的虛擬機器,其中一臺為 primary ,另一臺為 backupbackup 備份了 primary 的所有執行 。當 primary 出現故障時,backup 可以上線接管 primary 的工作,以此來提供容錯 。


2. 主/備份方法

實現容錯伺服器的一種常見方法是 主/備份方法backup 狀態與 primary 保持相同,primary 故障時,使用 backup 進行接管。並且以這種方式將故障對於 client 隱藏,不會丟失任何資料 。

主/備份方法中保持狀態同步的方法有以下兩種:

  • State transferprimary 持續地將所有狀態( 包括 CPU、記憶體和 I/O 裝置 )變化傳送給 backup 。這種方法所需頻寬非常大 。
  • Replicated state machine:將伺服器抽象為確定性狀態機 。讓 primarybackup 按照相同的順序執接收相同的輸入請求,對於不確定的操作使用額外的協調來保證主備狀態一致 。這種方法實現複雜,但是所需頻寬較小 。本文便是採用這種方法 。

確定性狀態機:多臺狀態機從相同的初始狀態開始、按照相同的順序執行相同的操作,則它們的最終狀態是一致的 。

狀態機方法允許 primarybackup 進行更大的物理分離 。


3. 虛擬機器的選擇

虛擬機器 ( virtual machine ) 不是通過硬體來啟動作業系統,而是在硬體之上會呼叫一個 HypervisorHypervisor 的工作實際上就是在硬體上模擬多個虛擬計算機 。Hypervisor 上執行著 GuestOS ,再上面是應用程式 。

Hypervisorvirtual machine monitor ( VMM )

GuestOS 即執行在虛擬機器中的作業系統,與之對應的是 HostOS ,指物理機裡的作業系統 。

在物理機上確保確定性執行是困難的,因為其會接收到很多不確定輸入( 如定時器中斷 ),因此可以採用虛擬機器,Hypervisor 對硬體進行模擬和控制,可以捕獲到這些不確定輸入的所有相關資訊,使得 backup 可以重放這些不確定輸入 。

因為我們討論的故障主要是指伺服器故障,因此不同的虛擬機器要位於不同的物理機上,否則便失去了容錯的意義 。


4. 基本設計

4.1 基本架構

Primary VMBackup VM 執行在同一網路環境中的不同物理機上,兩者可以訪問同一個 Disk Server ,即論文當中的 Shared Disk

只有 Primary VM 向外界通知自己的存在,因此所有網路輸入或其他輸入(磁碟、滑鼠、鍵盤)都進入 Primary VM

Primary VM 接收的所有輸入都通一個稱為 Logging Channel 的網路連線傳送到 Backup VM ,以保證兩者狀態相同 。Backup VM 的指令執行結果與 Primary VM 的結果相同,但只有 Primary VM 返回給 client 結果,Backup VM 的結果會被 Hypervisor 丟棄 。

系統使用 Primary VMBackup VM 之間的心跳包和 Logging Channel 上的流量監控來檢測 Primary VMBackup VM 是否是失效 。此外,必須確保 Primary VMBackup VM 中只有一個接管執行 。

事實證明,這些主備虛擬機器並不適用於本地磁碟,而是會和某些磁碟伺服器進行通訊。( 論文中並未提到這點 )

4.2 確定性重放

由上文可知,VM-FT 建模為確定性狀態機的複製 。對於一系列輸入,對 primary 的執行進行記錄並確保 backup 以相同方式執行的基本技術稱為 確定性重放

primary 的操作中包含了 確定性操作不確定性操作 。確定性操作在 primarybackup 上的執行結果是相同的,不確定性操作包括:

  • 來自 client 的輸入,這些輸入可能在任何時候到達
  • 非確定性指令,如隨機數生成指令、在不同時間獲得時間的指令、生成裝置唯一 ID 的指令等
  • 多核併發,服務中的指令會在不同的核上何以某種方式交錯執行,執行順序不可預測( 本論文中的方法只針對單核處理器,不解決此問題 )

前兩種不確定性操作會在 Logging Channel 中傳送

確定性重放記錄 primary 的輸入和 primary 執行相關的所有可能的不確定性,記錄在 log entry 流中,傳送給 backup 並使其重放 :

  • 對於不確定的操作,將記錄足夠的資訊,確保其在 backup 上重新執行能夠得到相同的狀態和輸出
  • 對於不確定的事件,如定時器或 IO 完成中斷,事件發生的確切指令會被記錄下來,重放時,backup 會在指令流中相同的位置重放這些事件

log entry 中應該包含了:

  • 事件發生時的指令號
  • 型別,指明是網路輸入還是其他指令
  • 資料:資料包裡的資料,若是不確定指令,則此資料是該指令在 primary 的執行結果,所以 backup 就可以對該指令提供與 primary 相同的執行結果

不確定性指令執行過程:

( 即使 primarybackup 在同一狀態,執行不確定性指令後也會產生不同結果 )

primary

  • Hypervisorprimary 執行指令時設定中斷
  • Hypervisor 執行指令並記錄結果
  • 傳送結果和指令序號到 backup

backup

  • Hypervisorlog entry ,在該指令序號處設定中斷
  • Hypervisor 應用從 primary 執行得到的結果,自己產生的結果被丟棄,從而保證主備一致

4.3 輸出要求和規則

輸出要求:若 primary 發生故障後且 backup 接管後,backup 必須以一種與原 primary 已傳送到外部的輸出完全一致的方式執行 。

只要滿足了輸出要求,故障轉移就不會丟失外部可見的狀態或資料,client 也不會注意到 server 服務中斷或有不一致 。

可能有一種特殊情況會發生:如果 primary 在執行輸出操作後立即故障,backup 在完成接管之前,可能還未執行到同樣的輸出操作,就被其他不確定事件所影響( 如計時中斷 ),這樣 backup 就無法以與 primary 發生故障時的相同狀態上線,為此提出了 輸出規則

輸出規則primary 必須延後將輸出傳送到外部世界的動作,直到 backup 已經接收並確認 與產生該輸出的操作相關 的 log entry

基於輸出規則,primarybackup 的互動如下圖所示:

primary 等待來自 backupACK 時,不會停止執行,只需要延遲輸出的傳送 ( 非同步執行 )。

一些故障發生情況

  • 如果 primary 在收到 ACK 之前故障,它不會返回結果給 client ,由於 backup 的輸出會被丟棄,所以兩者在 client 看來是一致的,即未收到 server 回覆 。

  • 如果 primary 在傳送輸出後故障,backup 在接管後也執行傳送,client 會收到兩次輸出 。但是這種情況不會造成不良後果,因為對於 TCP 連線來說,它會處理重複的資料包;對於磁碟來說,會對同一塊儲存區覆蓋寫入 。

4.4 檢測和響應故障

兩種 VM 都有可能發生故障:

  • 如果是 backup 故障,primary 將停止在 logging channel 上傳送 log entry ,並繼續執行
  • 如果是 primary 故障,backup 會繼續重放 log entries ,重放結束後 上線 成為 primary ,此時,它可以向外界生成輸出 。

VM-FT 檢測故障的方式有 UDP 心跳檢測和監控 logging channel 中的流量以及 backup 傳送給 primaryACK 。若心跳或日誌流量停止的時間超過了特定超時時間( 大約幾秒 ),就會宣告故障 。

這樣的故障檢測方法,在有網路故障時,容易遇到 split-brain 問題:即 primarybackup 之間通訊斷開,但此時 primary 還在執行,若 backup 此時上線,會造成兩者同時執行的問題,可能會導致資料損壞 。

為解決 split-brain 問題,使 Disk Server 支援 atomic test-and-set 測試,即在 Disk Server 上維護一個 flag ,第一個訪問此 flagVM 會成為 primary ,第二個訪問此 flagVM 不會上線 。( 類似於鎖 )

4.5 恢復冗餘

primary 發生故障,backup 上線時,在新的物理機上建立 backup ,恢復冗餘,繼續進入到容錯狀態 。

VM vSephere 實現了一個叢集服務,用於維護管理和資源資訊。當發生故障時,叢集服務根據資源使用情況和其他約束來確定新的 backup 的最佳伺服器,並將其複製成為 backup 。其結果是,VM-FT 通常可以在伺服器發生故障後幾分鐘內重新建立冗餘,而在執行容錯轉移時不會產生任何明顯的中斷 。

4.6 管理日誌通道

Hypervisorprimarybackup 分別維護了一個 log buffer ,如下圖所示:

  • primary 執行時,會將 log entry 生成到 log buffer 當中
  • primarylog buffer 會盡快將內容清除到 logging channel
  • log entry 一到達 logging channel 就會被讀到 backuplog buffer
  • backup 傳送 ACKprimary

primarylog buffer 已滿,primary 會等待;若 backuplog buffer 已空,backup 會等待 。

另外,為了防止 backup 的重放落後太多,在傳送和確認 log entry 的協議中,會傳送附加資訊來確定 primarybackup 之間的 實時執行延遲 ,通常小於 100ms 。若 backup 出現明顯的延遲,VM-FT 會通知排程器給它分配更少的 CPU 資源,從而降低 primary 的速度;若 backup 追起來了,逐漸增加 primary 的速度 。

4.7 磁碟的記憶體訪問競爭

磁碟操作可能和 VM 中的應用程式或 OS 存在記憶體訪問競爭 。

這種競爭在網路資料包或磁碟塊到達 primary 時產生 。在沒有 VM-FT 的情況下,相關硬體會通過 DMA 將該資料複製到記憶體中 。若 APP/OS 也在同時讀取這塊記憶體。那麼對於 primarybackup ,由於時間上的微小差異,可能一個在 DMA 之前讀取,一個在 DMA 之後讀取,就導致了不一致 。

解決方法是使用 bounce buffer ,它的大小與磁碟操作訪問的記憶體大小相同 。primaryHypervisor 首先複製網路資料或磁碟塊到 bounce buffer ,此時 primary 無法訪問它 ,Hyperbisor 中斷 primary 使其暫停執行,並記錄中斷的指令 。然後 Hypervisorbounce buffer 中的內容複製到 primary 的記憶體 ,並讓其繼續執行 。通過 logging channel 將資料送到 backup 之後,backupHypervisor 在相同指令處中斷 backup ,將資料複製到 backup 的記憶體後,最後恢復 backup 的執行 。


5. 機器級複製和應用級複製

5.1 機器級複製

機器級複製 即複製了記憶體中和暫存器中的所有內容 。優點為可以在 VM-FT 上執行任何軟體;缺點為不夠高效

5.2 應用級複製

應用級複製primary 僅傳送 high-level 操作給 backup 。如資料庫,同步的狀態僅為資料庫內容,不是所有的記憶體內容,操作僅為資料庫命令( getput 之類 ),沒有網路包或中斷 。GFS 使用的也是應用級複製 。

優點:更少的細粒度同步、更低的開銷

缺點:應用程式必須理解系統的容災


6. VM-FT 和 GFS 容錯的比較

VM-FT 備份的是 計算,可以用它為任何已有的網路伺服器提供容錯性。VM-FT 提供了相當嚴謹的一致性而且對 clientserver 都是透明的。例如,你可以利用 VM-FT 為已有的郵件伺服器提供容錯性。

相比之下,GFS 只為 儲存 提供容錯性。因為 GFS 只針對一種簡單的服務提供容錯性,它的備份策略會比 VM-FT 更為高效:例如,GFS 不需要使中斷髮生在所有的副本的同一指令上。GFS 通常只會被用作一個對外提供完整容錯服務的系統的一部分:例如,VM-FT 本身也依賴了一個在主備虛擬機器間共享的有容錯性的儲存服務,而你則可以用類似於 GFS 的東西來實現這個模組( 雖然從細節上來講 GFS 不太適用於 FT )。


相關文章