MIT 6.824 分散式系統課程第四課:主備複製

ty4z2008-github發表於2020-03-28

筆記: Lecture 4: Primary/Backup Replication

視訊:Lecture 4: Primary-Backup Replication

論文地址:The design of a practical system for fault-tolerant virtual machines

課程概要

業界容錯的解決方案之一是主備複製,通過學習 VMware FT 看看具體如何實現,以及主備遇到的問題。

正文

容錯的目的

  • 保證服務的可用性
  • 伺服器和網路都會出現故障,但是使用副本容錯還是必不可少

複製副本並不是銀彈

  • 單個副本的容錯

    風扇停止執行、CPU 超載導致主機停機、電源線拔了、光纜被挖。因為磁碟空間不足導致軟體停止。

  • 硬體缺陷、軟體 bug、或者是配置錯誤。這些可以導致一時間所有的副本都當機。(其實配置問題只需要增加校驗的步驟也可以解決)

  • 出現地震或者是全城停電。(這裡要有異地副本)

複製副本的開銷如何?頻寬、磁碟、額外的伺服器

目前兩種主要的複製方式:

  • 狀態複製

    主節點負責執行寫、寫完之後傳送最新的狀態給副本

  • 複製狀態機

客戶端傳送狀態至主節點,主節點按順序執行並且傳送給副本。所有的副本執行相同的動作。相同的開始狀態、操作、順序、最終態狀態複製傳輸比較簡單,方式狀態可能會比較多,網路傳輸速度太慢

複製狀態機往往用的網路更少,它的特徵主要是進行狀態比較,但是對於保證正確性需要做很多工作。VM-FT 就是使用這個模式

本課重點

  • 複製什麼狀態
  • 主節點是否需要等待備節點
  • 什麼時候進行主備切換?
  • 主備切換時異常如何處理?
  • 如何快速的進行主備切換?

在生產環境中,主備的同步要到什麼程度?

  • 應用狀態的同步,eg:資料庫表。GFS 是這種方式,主節點會把高優先順序的操作傳送給副本(譬如:檔案寫入。計算機時鐘中斷則不同步)。應用程式碼需要理解容錯,對於流的新舊要校驗
  • 機器級別,eg:暫存器和 RAM 內容都同步

    需要我們同步複製主節點所有的操作(中間過程不再加工資料),機器事件也會轉發(中斷、DMA 內容、&c),事件流保持完整同步。除非是機器差異產生的差別。對於指令並不是真正意義上的執行該指令,而是應用通過指令得出最後的結果。這一切是在軟體層面完成

VMware FT 屬於機器級別的狀態複製,可以執行在不通架構的伺服器和系統之上(相容),對於客戶端來說整體還是單體作業系統,無任何感知保持透明。

論文概覽

FT 的架構

FT 通訊協議

術語:

hypervisor==monitor(監控)== VMM(虛擬機器監控)

O/S+app 指代在虛擬機器中執行的應用程式(作業系統、應用軟體)

兩臺機器,一臺主,一臺副本

主節點通過網路(日誌通道 log channel)傳送所有的外部事件(客戶端包)至副本,日誌是有順序的。當主備其中某一個出現故障時,都會變成單機,如果是備會變為主,此時無副本。如果是備出現故障,主的事件會丟失。

VMM 會模擬本地磁碟介面,虛擬機器操作檔案時。與訪問實際磁碟的呼叫一致。但實際上儲存在網路儲存上,通常只有主和儲存伺服器通訊(副本只是讀取),當副本變為主節點時才對儲存進行通訊。因為是儲存在統一的物理磁碟上,在副本出現故障時,新的副本不需要拷貝資料,就能很快的啟動。

主節點何時必須像副本傳送資訊?

當出現可能導致會產生不一致的時候,就需要立即傳送(例如檔案更新)。任何導致結果不一致的不確定指令也需要同步。

有哪些動作需要 FT 介入處理?

當記憶體和暫存器相同時,大多數的指令在主備上各自的結果都一致。但是有些不確定的指令就需要 FT 處理,例如來自外部的輸入事件——網路資料包、DMA 資料 + 中斷、時鐘中斷、非狀態指令(讀取當前時間、隨機數)、多核並行任務的執行(多執行緒在多次執行時對鎖的搶佔順序是會不同)。

當出現主備出現分歧時,會導致什麼後果?

副本的 b/c 狀態與主節點的狀態不一致,如果此時出現主節點當機,客戶端就會看到資料不一致。

例子:GFS 租約過期

假設 GFS 的 master 是有副本,chunkserver 在租約過期前的 60s 就傳送續期指令。(時鐘中斷管理伺服器時間)

在 master 上,收到請求後發生時鐘中斷。此時主節點對 chunkserver 進行續約

在 backup 上,時鐘中斷在請求之前發生,此時副本記錄的 chunkserver 已經過期了。

假設此時主節點崩潰,失效的主節點被副本接管。副本發現之前的 chunkserver 已經過期了,需要重新選擇新的 chunkserver。那麼此時在系統中就會出現兩個 chunkserver 都持有合法的租約。

因而要求:副本要和主節點所有事件都同步、順序一致、保持指令流的一致性。

FT 的日誌包含三部分:指令、型別、資料

FT 是如何處理時鐘中斷的?

理想狀態:主備在同一事件流所看到的指令是一致的。

主:

  1. FT 發生時鐘中斷
  2. FT 從 CPU 中讀取指令編號
  3. FT 傳送指令 X 的時鐘中斷到日誌通道(log channel)
  4. FT 分發中斷給主節點,然後恢復正常

這些依賴 CPU 需要支援在執行 X 條指令後發生時鐘中斷

備:

  1. 忽略自己的時鐘中斷
  2. FT 獲取所有日誌條目之前,未執行的指令
  3. FT 告訴 CPU 在指令 X 時,進行中斷
  4. FT 模擬計時器中斷,進行備份操作

FT 是如何處理網路包的(請求包)?

主:

  1. FT 告訴網路卡(NIC),拷貝一份資料包到 FT 的私有回彈緩衝區(bounce buffer)
  2. NIC 有時會執行完 DMA 後才進行中斷
  3. FT 捕獲到中斷
  4. FT 暫停主節點
  5. FT 複製剛剛第一步儲存在 bounce buffer 的資料到主節點記憶體
  6. FT 在主節點中模擬 NIC 中斷
  7. FT 傳送網路資料包和指令 # 到副本

備:

  1. FT 從 log stream 中 獲取到資料和指令 #
  2. FT 通知副本 CPU 在指令 X 處中斷
  3. FT 拷貝網路包資料到副本記憶體中,並且在副本中模擬 NIC 中斷

為什麼會引入 bounce buffer?

主要是為了資料在主備節點中,能在合適的時間得到處理,而不會接收到資料包就開始處理,不利於回放。

注意:副本需要滯後一個日誌記錄處理

假設主節點在指令 X 之後,進來一箇中斷或者是輸入。備份伺服器在獲得指令 X 後就開始了執行,那麼此時的輸入的結果就無法在副本中重放,因為副本的已經執行完了指令 X,而新進來的輸入或者是中斷需要等待下一個指令來結束。(類似檔案結束符)

舉例:非確定指令

在現實生產環境中,即使主備的狀態一致,但是還是會出現相同的指令產生不同的結果。例如:讀取當前時間、隨機數、處理器序列號、時鐘週期

主節點執行指令的流程:

  1. 主節點執行指令,FT 呼叫 CPU 執行中斷
  2. FT 執行指令並且記錄結果
  3. 傳送結果和指令給副本節點

副本節:

  1. FT 讀取日誌,根據指令生成中斷
  2. FT 根據主節點需要的結果返回資訊

執行結果響應流程:

  1. 主備節點執行指令後都會輸出結果
  2. 主節點的輸出結果為實際結果
  3. 備節點的結果會被忽略(只作為主節點返回結果的准許)

執行結果響應案例:資料庫伺服器

客戶端傳送 “自增” 請求給資料庫,資料庫實行自增後儲存資料,並返回新的值給客戶端。

  1. 主節點儲存的值是 10
  2. 客戶端發起自增請求
  3. FT 分發請求到主備節點
  4. 主節點增加到 11,並響應結果給 FT,FT 響應回客戶端
  5. 副本節點執行,增加到 11,並響應給 FT
  6. 客戶端得到結果 11

但是:

假設主節點在傳送結果後當機,客戶端得到的結果是 11

logging channel 丟失了客戶端的寫請求,因為主節點已經當機不會再次傳送

副本會變為主節點,此時副本內的值還是 10。

客戶端此時發起一個 “自增” 請求,得到的結果不是 12,而是 11。

解決方式:改變結果的輸出規則(論文 2.2)

主節點傳送結果之前,必須先收到副本的響應才能傳送結果

主節點:

  1. 收到客戶端的自增請求
  2. 傳送客戶端請求到 logging channel
  3. 主節點快取當前結果
  4. 等待副本響應已經收到日誌
  5. 響應結果給客戶端

假設主節點收到副本響應前後在某個時間點當機:

  1. 在收到副本響應前當機

副本是看不到客戶端請求的,並且不會自增。主無應答

  1. 在收到副本響應後當機

    客戶端可能看到 “11” 的響應結果,副本肯定已經收到客戶端的寫請求。並且值為 11

結果響應規則是一個 trade off 問題,在所有的複製系統中都有可能出現。它會直接影響系統的效能。有時是可以取捨的,例如在等待響應前,結果為只讀操作,得到響應後才可以再次修改。而 FT 是非應用級別響應,這裡需要等待副本響應結果。

論文討論

Q:如果主節點在收到副本節點響應後立即當機(還未返回給客戶端),那麼客戶端是否永遠等待響應結果?

A:當主節點當機,副本提升為主節點時,會出現以下情況:

  1. 副本會消化完日誌流中的資料
  2. 消化日誌時所產生的輸出被丟棄
  3. 日誌消化完後,副本變為主節點,此時結果不再丟棄

在例子裡面,最後一條日誌是客戶端的請求指令,當客戶端請求結果時,所看到的值是最新的值,這個結果有新晉升為主節點的副本返回

Q:假設主節點在返回結果後當機,副本會不會返回兩次?

A:這個是有可能的,如果是 TCP,那麼會收到重複序號的資料包。如果是寫磁碟,會再寫一份同樣的資料到相同的塊。

在複製系統中,主副本替換產生兩次結果響應是很常見的情景,客戶端需要讓狀態具有冪等性。相同的請求,多次執行結果不變。

Q:假設 FT 產生的網路分割槽,是否會導致 “腦裂”?如果主節點和副本都假設對方已經當機,他們是否都變為主節點?

A:共享儲存的磁碟服務已經解決了這個問題,磁碟服務支援原子 TSL(原子檢查並設定)操作,主副節點遇到物件已經當機,都會試圖進行 test-and-set 操作,如果只存在一個存活,在進行 test-and-set 後並上線,但是假設兩者都試圖修改,其中有一方會失敗,失敗的晉升請求會被忽略。

不過磁碟伺服器可能會有單點故障問題,磁碟服務當機,整個服務也會當機。這裡可能需要引入支援複製的磁碟伺服器

Q:為什麼不支援多核處理器?

A:並行執行,無法保證能達到機器級別的指令執行結果保持統一

效能(圖表 1)

FT/非 FT:效能差別較小

日誌頻寬:MySQL 的磁碟 + 網路傳輸可以達到 18Mbits/秒

總體來看,這些結果其實比較偏低。一塊 SSD 磁碟可以達到 400Mb/秒,這個資料看起來是這些應用不怎麼依賴磁碟

FT 適合應用於什麼場景?

關鍵但壓力低的服務,例如域名伺服器。其軟體的修改比較低的服務

吞吐量大的服務如何選擇複製?

在工業界,常見使用的複製是應用級別的複製,複製狀態機。例如資料庫。在資料庫中,狀態只有 DB,而不是這臺伺服器記憶體 + 磁碟的所有資料。對應的事件是 get 和 set 操作,而不是資料包和中斷。

優勢在於更少的顆粒度同步,並且開銷也小。GFS 使用的是應用級別的複製,Raft 也是為應用級別而誕生的

總結

主備複製這個常見,VM-FT 講述的很清晰,適合學習複製是什麼。但是 FT 是單點的,會有單點故障的風險。如果是為了效能,應選用應用級別的複製狀態機。

備註

聽過 VM 已經支援了多核 CPU,FT 已經被廢棄。

What’s New in vSphere 6.0: Multi-CPU Fault Tolerance

ReTrace: Collecting Execution Trace with Virtual Machine Deterministic Replay

參考資料

部落格地址

更多原創文章乾貨分享,請關注公眾號
  • MIT 6.824 分散式系統課程第四課:主備複製
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章