VMware FT 容錯技術(shù)詳解:原理、挑戰(zhàn)與實踐
VMware FT 容錯技術(shù)詳解:原理、挑戰(zhàn)與實踐
在現(xiàn)代計算環(huán)境中,業(yè)務連續(xù)性至關重要。服務器故障可能導致服務中斷、數(shù)據(jù)丟失,進而造成巨大的經(jīng)濟損失和聲譽損害。容錯 (Fault Tolerance, FT) 技術(shù)旨在確保單個硬件故障不會影響應用程序的可用性。VMware FT 就是這樣一種為虛擬機 (VM) 提供高級別可用性的解決方案,它通過在不同物理服務器上維護一個與主虛擬機 (Primary VM) 同步的備份虛擬機 (Backup VM) 來實現(xiàn)。
容錯的基本概念與方法
首先,我們需要明確 VMware FT 主要針對的是 失效-停止 (fail-stop) 型故障。這類故障指的是組件發(fā)生故障后會完全停止工作,例如電源故障、網(wǎng)絡中斷或整個服務器宕機。這類故障可以通過復制 (replication) 來處理。相比之下,一些更復雜的故障,如軟件缺陷 (software bug)、設計缺陷 (design flaw) 或惡意的拜占庭 (Byzantine) 故障(即組件可能產(chǎn)生錯誤結(jié)果但表面上仍在運行),則不在此類 fail-stop 容錯系統(tǒng)的主要處理范圍內(nèi)。
實現(xiàn)容錯的核心在于復制。通常有兩種主要的復制策略:
- 狀態(tài)傳輸 (State Transfer) :定期或持續(xù)地將主副本的完整狀態(tài)(包括 CPU、內(nèi)存、I/O 設備狀態(tài))傳輸?shù)絺浞莞北尽_@種方法的缺點是所需帶寬可能非常大,尤其是內(nèi)存變化頻繁時。
- 復制狀態(tài)機 (Replicated State Machine, RSM) :將服務器視為確定性狀態(tài)機。如果兩個狀態(tài)機從相同的初始狀態(tài)開始,并以相同的順序接收相同的輸入,那么它們將經(jīng)歷相同的狀態(tài)序列并產(chǎn)生相同的輸出。 VMware FT 正是采用了這種方法,通過在底層復制虛擬機內(nèi)存和寄存器的執(zhí)行來實現(xiàn)。這種方法的帶寬需求通常遠低于狀態(tài)傳輸。
VMware FT 的核心:基于 Hypervisor 的復制狀態(tài)機
Q: 為什么在虛擬機上實現(xiàn)確定性執(zhí)行比在物理服務器上更容易?
A: 因為 Hypervisor 模擬并控制了硬件的許多方面,例如中斷傳遞的精確時機。這使得 Hypervisor 能夠確保主虛擬機和備份虛擬機在面對相同的輸入時,其內(nèi)部狀態(tài)以完全相同的方式演進。
Q: 什么是 Hypervisor?
A: Hypervisor,也稱為虛擬機監(jiān)視器 (Virtual Machine Monitor, VMM),是虛擬機系統(tǒng)的一部分。它模擬一臺完整的計算機,客戶操作系統(tǒng) (Guest OS) 及其應用程序運行在這個模擬的計算機(即虛擬機)內(nèi)。在 VMware FT 架構(gòu)中,Primary VM 和 Backup VM 都是運行在各自 Hypervisor 內(nèi)的客戶機。
VMware FT 的基石是 確定性重放 (Deterministic Replay) 技術(shù)。 Primary VM 的所有輸入(如網(wǎng)絡數(shù)據(jù)包、磁盤讀取、鍵盤鼠標操作以及所有可能導致非確定性行為的事件(如中斷的時間、讀取 CPU 時鐘周期計數(shù)器)都會被 Hypervisor 捕獲。這些輸入和非確定性事件被記錄成日志條目,通過一個專用的 日志通道 (Logging Channel) 實時發(fā)送給 Backup VM。 Backup VM 的 Hypervisor 則嚴格按照這些日志條目來“重放”Primary VM 的執(zhí)行過程,從而保持兩者狀態(tài)的精確同步,盡管 Backup VM 的執(zhí)行會略有延遲。
Q: VMware FT 如何處理那些看似隨機的非確定性事件,以確保主備一致?
A: Hypervisor 控制了所有隨機性的來源。
- 中斷傳遞 :Hypervisor 會記錄 Primary VM 中斷發(fā)生的精確指令位置,并在 Backup VM 執(zhí)行到相同指令時傳遞該中斷。這得益于 CPU 的性能計數(shù)器 (performance counters) 等硬件輔助特性。 VMware 的實現(xiàn)足夠高效,無需像早期某些系統(tǒng)那樣將中斷延遲到某個“紀元 (epoch)”結(jié)束時才處理。
- 時間或硬件周期計數(shù)器 :當應用程序試圖讀取當前時間或硬件周期計數(shù)器時,Hypervisor 會攔截這些指令,并確保 Primary VM 和 Backup VM 獲取到相同的值。
- 隨機數(shù)生成器 :即使應用程序調(diào)用隨機數(shù)生成器,Hypervisor 也會確保主備獲得相同的隨機數(shù)序列。
關鍵挑戰(zhàn)與解決方案
1. 輸出規(guī)則 (Output Rule) 與數(shù)據(jù)一致性
Q: VMware FT 如何保證在 Primary VM 故障后,Backup VM 接管時不會丟失數(shù)據(jù)或產(chǎn)生外部可見的不一致狀態(tài)?
A: 這是通過嚴格遵守 輸出規(guī)則 (Output Rule) 來實現(xiàn)的。
輸出規(guī)則 :Primary VM 在向外部世界發(fā)送任何輸出(例如網(wǎng)絡數(shù)據(jù)包、磁盤寫入到共享磁盤)之前,必須等待 Backup VM 接收并確認了與該輸出操作相關的日志條目。
這條規(guī)則至關重要。如果 Backup VM 已經(jīng)確認收到了包含某個輸出操作的日志,那么即使 Primary VM 在該輸出實際發(fā)送后立即崩潰,Backup VM 也能準確地重放到該輸出點之前的狀態(tài),并最終產(chǎn)生與 Primary VM 相同的輸出(或達到一個與該輸出一致的狀態(tài))。如果沒有這個規(guī)則,Backup VM 可能在沒有收到所有必要日志的情況下就上線,導致其狀態(tài)與 Primary VM 已經(jīng)發(fā)出的輸出不一致。
值得注意的是,輸出規(guī)則僅僅延遲了輸出的實際發(fā)送,Primary VM 本身可以繼續(xù)執(zhí)行后續(xù)指令,而不會被完全暫停。這與一些早期系統(tǒng)要求 Primary VM 在輸出前必須完全停止直到 Backup VM 確認的做法不同。
Q: 如果 Primary VM 在發(fā)送輸出后立即失敗,輸出會重復嗎?這會導致問題嗎?
A: Backup VM 在接管后很可能會重復該輸出。對于大多數(shù)情況,這不是問題:
- 網(wǎng)絡輸出 :如果輸出是網(wǎng)絡數(shù)據(jù)包,接收端的 TCP 協(xié)議棧通常能自動處理和丟棄重復的數(shù)據(jù)包。
- 磁盤 I/O :磁盤寫入操作通常是冪等的 (idempotent),即多次執(zhí)行相同的寫操作(寫入相同數(shù)據(jù)到相同位置且中間無其他 I/O)與執(zhí)行一次的效果相同。
2. DMA 競爭 (Race) 與 Bounce Buffers
Q: 什么是 DMA (Direct Memory Access) 競爭?VMware FT 如何避免由此導致的非確定性?
A: 當硬件設備(如網(wǎng)卡或磁盤控制器)通過 DMA 直接向虛擬機內(nèi)存寫入數(shù)據(jù)時,如果客戶機操作系統(tǒng)或應用程序恰好在幾乎同一時刻讀取該內(nèi)存區(qū)域,就可能發(fā)生競爭。由于主備虛擬機執(zhí)行時序的微小差異,一個可能讀到新數(shù)據(jù),另一個可能讀到舊數(shù)據(jù),從而導致狀態(tài)發(fā)散。
VMware FT 通過使用 bounce buffers 來避免這個問題:
- 當網(wǎng)絡數(shù)據(jù)包或磁盤數(shù)據(jù)塊到達 Primary VM 時,數(shù)據(jù)首先被 DMA 到 Hypervisor 控制的一個私有“bounce buffer”中,這個 buffer 是 Primary VM 無法直接訪問的。
- DMA 完成后,F(xiàn)T Hypervisor 中斷 Primary VM 的執(zhí)行,并記錄下中斷發(fā)生的精確指令點。
- 然后,F(xiàn)T Hypervisor 將 bounce buffer 中的數(shù)據(jù)復制到 Primary VM 的實際目標內(nèi)存中。
- 之后,Primary VM 才被允許恢復執(zhí)行。
- 同時,這份數(shù)據(jù)會通過日志通道發(fā)送給 Backup VM。 Backup VM 的 FT Hypervisor 會在相同的指令點中斷 Backup VM,將數(shù)據(jù)從其自己的 bounce buffer(或直接接收到的數(shù)據(jù))復制到 Backup VM 的內(nèi)存中,然后恢復其執(zhí)行。
通過這種方式,確保了主備虛擬機在完全相同的執(zhí)行時刻“看到”輸入數(shù)據(jù),從而消除了 DMA 競爭。盡管 bounce buffer 會增加一點開銷,但通常不會造成明顯的性能損失。
3. 故障檢測與切換 (Failover)
VMware FT 系統(tǒng)使用多種機制來檢測 Primary VM 或 Backup VM 的故障:
- 在運行 FT 虛擬機的服務器之間進行 UDP 心跳檢測 (heartbeating)。
- 監(jiān)控日志通道上的流量。由于客戶機操作系統(tǒng)通常有規(guī)律的定時器中斷,日志流量應該是持續(xù)的。如果日志條目或確認信息流中斷超過預設的超時時間(通常幾秒鐘),則可能表明發(fā)生了故障。
當檢測到故障時:
- 如果 Backup VM 失敗,Primary VM 會“上線 (go live)”,即停止記錄日志并轉(zhuǎn)為普通模式運行。
- 如果 Primary VM 失敗,Backup VM 的上線過程稍微復雜:它必須首先消耗掉其日志緩沖區(qū)中所有已接收但尚未處理的日志條目,以使其狀態(tài)達到 Primary VM 失敗前的最新點。完成后,Backup VM 停止重放模式,轉(zhuǎn)為新的 Primary VM,并開始向外部世界產(chǎn)生輸出。此時,F(xiàn)T 系統(tǒng)會自動更新網(wǎng)絡,例如通告新 Primary VM 的 MAC 地址,以便網(wǎng)絡交換機能將流量導向正確的服務器。
4. 腦裂 (Split-Brain) 問題及其解決
Q: 什么是腦裂 (split-brain) 問題?VMware FT 如何防止這種情況?
A: 當 Primary VM 和 Backup VM 之間的網(wǎng)絡連接中斷(網(wǎng)絡分區(qū)),但它們各自的物理服務器仍在運行時,可能會發(fā)生腦裂。雙方都可能錯誤地認為對方已經(jīng)崩潰,并嘗試獨立“上線”成為唯一的活動虛擬機。如果兩者都成功上線,將導致數(shù)據(jù)損壞和客戶端混淆。
VMware FT 使用 共享存儲 (Shared Storage) 上的一個原子性 test-and-set 操作作為決勝機制 (tie-breaker) 來解決腦裂問題。
- 共享存儲上維護一個初始為 false 的標志。
- 當 Primary VM 或 Backup VM 認為對方失效并決定自己上線時,它會首先向共享存儲發(fā)送一個 test-and-set 請求。
- 存儲服務會原子地執(zhí)行類似以下邏輯的操作:
test-and-set() {
acquire_lock()
if flag == true:
release_lock()
return false // 已經(jīng)被設置過了,你不能上線
else:
flag = true
release_lock()
return true // 設置成功,你可以上線
}
- 只有當 test-and-set 操作返回 true 時,該虛擬機才被允許上線。如果返回 false,意味著另一方已經(jīng)成功上線(或正在上線),當前虛擬機則會停止自己(“自殺”)以避免沖突。如果虛擬機無法訪問共享存儲,它會等待直到可以訪問為止。
這種機制確保了即使在網(wǎng)絡分區(qū)的情況下,也只有一個虛擬機能夠成功上線。
5. 啟動與重啟 FT 虛擬機
為了能夠啟動一個新的 Backup VM 與一個正在運行的 Primary VM 同步,或者在故障后重新建立冗余,VMware FT 使用了一種修改版的 VMotion 技術(shù),稱為 FT VMotion。
- FT VMotion 可以在不顯著中斷 Primary VM 執(zhí)行的情況下(通常暫停時間小于1秒),在另一臺服務器上克隆出一個與 Primary VM 狀態(tài)完全相同的 Backup VM,并自動建立起它們之間的日志通道。
- 當發(fā)生故障后,比如 Primary VM 失效,原來的 Backup VM 上線成為新的 Primary VM。此時,為了恢復冗余,這個新的 Primary VM 會通知集群管理服務 (clustering service)。集群服務會根據(jù)資源使用情況在集群中選擇一臺合適的服務器,并調(diào)用 FT VMotion 來創(chuàng)建并啟動一個新的 Backup VM。這個過程通常能在幾分鐘內(nèi)自動完成。
6. 日志通道管理
- 主備 Hypervisor 都會為日志條目維護大型緩沖區(qū)。 Primary VM 產(chǎn)生日志到其緩沖區(qū),Backup VM 從其緩沖區(qū)消耗日志。
- Primary 的日志緩沖區(qū)內(nèi)容會盡快發(fā)送到日志通道,Backup 會盡快從通道讀取到自己的緩沖區(qū)。 Backup 在讀取日志后會向 Primary 發(fā)送確認 (acknowledgments)。這些確認用于 Output Rule 的判斷。
- 如果 Backup 的日志緩沖區(qū)為空,它會暫停執(zhí)行等待新日志。
- 如果 Primary 的日志緩沖區(qū)已滿(通常因為 Backup 處理過慢或網(wǎng)絡擁塞),Primary VM 必須暫停執(zhí)行,這是一種自然的流控機制。為避免這種情況影響 Primary VM 性能,系統(tǒng)會監(jiān)控主備之間的執(zhí)行延遲。如果 Backup VM 落后太多(例如超過1秒),F(xiàn)T 系統(tǒng)會逐漸降低 Primary VM 的 CPU 分配,使其放慢速度,以便 Backup VM 能跟上。
7. 磁盤 I/O 的特殊處理
- 共享磁盤 (Shared Disk) :在默認配置中,Primary VM 和 Backup VM 共享虛擬磁盤(如通過 Fibre Channel 或 iSCSI SAN 訪問)。此時,只有 Primary VM 實際執(zhí)行對共享磁盤的寫操作,這些寫操作也受 Output Rule 的約束。 Backup VM 不執(zhí)行寫操作,其輸出會被 Hypervisor丟棄。
- 非共享磁盤 (Non-shared Disk) :也支持主備各自擁有獨立的(非共享的)虛擬磁盤。在這種情況下,Backup VM 也會執(zhí)行所有磁盤寫操作到它自己的虛擬磁盤上,從而保持與 Primary VM 磁盤內(nèi)容的同步。這種配置下,Primary VM 的磁盤寫操作不再被視為外部輸出,因此不需要遵循 Output Rule 進行延遲。這對于共享存儲不可用或主備距離較遠 (“l(fā)ong-distance FT”) 的場景很有用。
- Primary 故障時未完成的磁盤 I/O
Q: 當 Primary VM 發(fā)生故障時,那些已經(jīng)發(fā)起但可能尚未在物理磁盤上完成的 I/O 請求如何處理?
A: 當 Backup VM 上線成為新的 Primary VM 時,在其“go-live”過程中,它會重新發(fā)出這些掛起的 (pending) I/O 請求。具體來說,日志中那些有 I/O 啟動記錄但沒有對應完成中斷記錄的 I/O 操作,都需要在 Backup VM 上線時重新啟動。由于 VMware FT 已經(jīng)通過 bounce buffer 等機制消除了 I/O 競爭,并且 I/O 操作明確指定了內(nèi)存和磁盤塊,因此這些重新發(fā)出的磁盤操作即使之前已經(jīng)成功完成過,再次執(zhí)行也是安全的(冪等性)。
8. 網(wǎng)絡 I/O 的挑戰(zhàn)與優(yōu)化
為了確保確定性,VMware FT 對網(wǎng)絡 I/O 的處理做了一些調(diào)整:
- 禁用了某些基于 Hypervisor 異步更新虛擬機網(wǎng)絡設備狀態(tài)的性能優(yōu)化。例如,接收緩沖區(qū)不能再由 Hypervisor 在 VM 執(zhí)行時直接異步更新,而是需要陷入 (trap) 到 Hypervisor,記錄更新操作,然后再應用到 VM。類似的,異步發(fā)送數(shù)據(jù)包的優(yōu)化也被禁用,發(fā)送操作也需要通過 trap 完成。
- 這些改變以及 Output Rule 帶來的發(fā)送延遲對網(wǎng)絡性能構(gòu)成挑戰(zhàn)。
- 優(yōu)化措施
a.聚集優(yōu)化 (Clustering Optimizations) :當 VM 以足夠高的比特率傳輸數(shù)據(jù)時,Hypervisor 可以將多個數(shù)據(jù)包的發(fā)送合并為一次 trap,甚至在某些情況下(如作為接收新包的一部分發(fā)送)可以做到零 trap。類似地,對接收到的數(shù)據(jù)包也可以合并中斷通知。
b.減少發(fā)送延遲 :關鍵在于減少日志消息發(fā)送到 Backup VM 并獲得確認所需的時間。通過確保日志條目和確認信息的發(fā)送與接收都可以在沒有線程上下文切換的情況下完成(例如使用類似 Linux tasklet 的延遲執(zhí)行上下文處理 TCP 數(shù)據(jù)接收),以及在 Primary VM 發(fā)送數(shù)據(jù)包時強制立即刷新相關日志條目,可以顯著降低延遲。
性能與局限性
VMware FT 在典型企業(yè)應用上的性能開銷通常小于10%。日志通道所需的帶寬對于多數(shù)應用也相當合理,一般低于 20 Mbit/s,遠低于 1 Gbit/s 網(wǎng)絡的承載能力。空閑的客戶機操作系統(tǒng)(如 Linux 和 Windows)產(chǎn)生的日志帶寬大約在 0.5-1.5 Mbits/sec,主要來自記錄定時器中斷的傳遞。
對于網(wǎng)絡密集型應用,特別是高接收速率的場景,日志通道帶寬可能成為瓶頸,因為所有接收到的網(wǎng)絡包都需要通過日志通道發(fā)送給 Backup VM。
目前,VMware FT 的生產(chǎn)版本主要支持單處理器 (uni-processor) 虛擬機。這是因為多處理器 (multi-processor) VM 的確定性重放仍然是一個具有挑戰(zhàn)性的研究領域,主要難點在于幾乎所有對共享內(nèi)存的訪問都可能構(gòu)成非確定性操作。不過,單處理器虛擬機對于許多工作負載已經(jīng)足夠,并且可以通過橫向擴展(使用多個單處理器VM)來滿足需求。
總結(jié)
VMware FT 通過在 Hypervisor 層面實現(xiàn)復制狀態(tài)機和確定性重放,為虛擬機提供了一種高效、透明的故障切換解決方案。它巧妙地解決了非確定性事件處理、輸出一致性、腦裂等關鍵問題,并通過一系列實用性設計(如 FT VMotion、自動恢復冗余)使其成為一個完整且易用的企業(yè)級容錯系統(tǒng)。盡管當前主要針對單處理器虛擬機和 fail-stop 故障,但其設計理念和實現(xiàn)為關鍵業(yè)務應用提供了堅實的保障。