重磅精品翻譯:QEMU-KVM虛機動態遷移原理

編者的話

本文翻譯者,KVM社區首席翻譯專家武楠。

本文詳細的介紹了虛擬化遷移的原理。

翻譯過程是怎樣一個過程,會有怎樣的收穫?

個人感覺是翻譯過程是一個挑戰自我,不斷完善自己,然後獲得提升的過程。

翻譯過程也是一個近距離和技術對話的過程,從字裏行間理解、揣摩技術的精髓,在翻譯成中文的時候斟酌,是一個反覆理解的過程,最終的收穫是知識。

請願意加入KVM社區翻譯羣的朋友聯繫羣主微信xiaoli173702,再技術翻譯的過程中我們一起討論,一起提升。

QEMU-KVM虛機動態遷移原理

在虛擬化領域,虛機動態遷移是一個非常有趣且持續不斷的話題:因爲隨着使用需求,客戶機變得越來越大(單個虛機的vCPU和RAM越來越多)且客戶機正常運行不間斷的需求也變得越來越嚴格。

本次討論將圍繞QEMU/KVM hypervisor早期在線遷移的簡單設計,例如到它是如何優化到當前的技術能力,未來將如何發展。這裏會探討在線遷移真正的工作原理,限制條件以及如何開發新思路設計來滿足最新在線遷移需求。

本次討論將涉及到已知的,未知的技術領域(例如TODO)以供感興趣的研究者再接再厲。

本文源於我最近發表在the devconf.cz conference.上的一個演講。膠片的PDF版可供參考,但你並不需要它來理解本文。本文是膠片的文本表示,是內容的詳細描述,對應我在演講過程中的闡述。

目錄

  • Virtualization 虛擬化

  • QEMU

  • KVM

  • Live Migration 在線遷移

  • QEMU Layout QEMU佈局

  • Getting Configuration Right正確的配置

  • Stages in Live Migration 在線遷移步驟

  • Ending Stage 2 (Transitioning from Live to Offline State第二階段(從在線遷移過渡到離線遷移)

  • Other Migration Code in QEMU 其他QEMU遷移代碼

  • VMState

  • VMState ExampleVMState 案例

  • Updating Devices 更新設備

  • Subsection Example

  • Things Changed Recently 最新變化技術

  • New Features 新特徵

  • Stuff That’s Lined Up

  • Future Work

Virtualization虛擬化

2a4200021fb09b90d955

我們從虛擬化棧總圖的左上角開始,用戶與虛機交互通過幾個界面:例如virt-manager, oVirt, OpenStack, or Boxes.這些軟件依次與Libvirt做交互,Libvirt可以提供支持多個hypervisor來管理虛機的API。Libvirt還提供與多種塊存儲和網絡設置做交互的API接口。

對於QEMU/KVM虛機,Libvirt使用QEMU API與QEMU對話,宿主機上的每臺虛機都是QEMU實例,客戶機作爲QEMU進程的一部分運行。使用top或者ps命令,可以看到每一個vCPU就是宿主機中單獨的一個線程。

QEMU與Linux做交互,尤其是Linux內部KVM模塊交互,是基於物理硬件運行,並不是在QEMU模擬環境中。

QEMU

  • Creates the machine 創建虛機

  • Device emulation code 模擬設備

  • some mimic real devices 模擬類型真設備(純軟虛擬化設備)

  • some are special: paravirtualized 半虛擬化設備

  • Uses several services from host kernel 源宿主機內核設備

  • KVM for guest control 客戶機控制器KVM

  • Networking 網絡設置

  • disk IO 磁盤IO

  • etc.

QEMU是一個虛擬化開源軟件,創建虛擬硬件環境來運行客戶機的操作系統。所有的虛擬硬件都是基於QEMU配置代碼創建的。客戶機操作系統,例如鍵盤,鼠標,網卡等等設備均是QEMU代碼實例,這些虛擬設備是基於技術參數的,開放給物理硬件使用,例如e1000系列的網絡設備。由於這些物理硬件的驅動已經經過調配,不需要經過修改的客戶機操作系統都可以識別這些設備。

除了模擬真實硬件(全虛擬化硬件),QEMU也專門爲提升虛擬化使用性能創建一些特殊的設備。對於QEMU/KVM虛機,我們使用virtio架構來創建這些設備,包括virtio-net網絡設備,virtio-blk塊設備,virtio-scsi SCSI設備,virtio-rng RNG設備等等。這些半虛擬化設備得益於採用虛擬化思路設計,所以它們比全虛擬化設備運行更快,更容易管理。

QEMU也與其他程序做交互,例如爲客戶機提供BIOS服務的SeaBIOS。

在操作上,QEMU藉助源宿主機Linux 內核的幾個設備,例如使用KVM APIs來控制客戶機,還會使用源宿主機網絡設置和存儲設備等等。

KVM

  • Do one thing, do it right做一件事就要將它做好

  • Linux kernel module Linux內核模塊

  • Exposes hardware features for virtualization to userspace將硬件支撐虛擬化特徵呈現給用戶

  • Enables several features needed by QEMU提供QEMU所需特徵

  • like keeping track of pages guest changes記錄客戶機變化頁

KVM是一個小型內核模塊,可以給Linux內核提供硬件虛擬化特徵。這種代碼負責將Linux內核轉化成hypervisor,KVM以典型的Linux或者Unix形式寫出來,它把內存管理,進程調度等工作交給Linux內核來決定這意味着,虛擬化層將及時受益於任何有關Linux內存管理的性能提升。

KVM將其API通過ioctls這個控制套接口暴露給用戶空間,QEMU是這些設備的用戶之一。KVM暴露給用戶空間的特徵之一是追蹤客戶機內存區域頁,例如前一個時段數據申請後客戶機進行修改等動作。這個特徵尤爲重要,我們在整個在線遷移過程都會使用到它。稍後我們會更多地談論到這點。

LiveMigration在線遷移

在客戶機運行過程中,從一個QEMU程序中獲取客戶機狀態,將其遷移到另外一個QEMU程序中。

客戶機不會感知到整體環境的變化。換句話說,客戶機不會牽扯到這個過程中,儘管如此,也許會感知到一點性能的降低。

  • 對負載均衡,硬件和軟件的維護,省電,檢測等都有用處。

在線遷移就是在客戶機仍在運行的情況下,將一個客戶機VM從一個hypervisor/QEMU程序,在另外一個上運行起來。客戶機持續正常工作,甚至不會意識到hypervisor的變化。在線遷移是將整個客戶機從一個物理宿主機轉移到另外一個。這意味着會涉及到很多變量:網絡帶寬,網絡延遲,存儲可用性等等。

使客戶機停止運行並讓新的hypervisor接管從而運行該客戶機的窗口期非常短。這樣可能導致客戶機應用程序性能降低,這是唯一使客戶機在遷移過程中暴漏之處。

在線遷移由很多好處:在一個服務器池中的幾個主機之間做負載,或者在客戶機運行的情況下,關閉一些主機對其硬件或者軟件進行維護,或者省電(如果一些主機主機在一個集羣中是輕負載的,並以可以承載更多VM而不影響服務,那麼更多的VM可以遷移到這個輕負載服務器上,關閉那些沒有使用的VM。

工程師還可以檢測VM,重新運行特定的流量,或者負載在VM上重複檢測,或者在VM上進行軟件調試。儘管檢測這種用戶案例與再現遷移無關,但是過去常常設置檢查點的代碼在QEMU內部是與在線遷移代碼共享的。

QEMU佈局

2a400000dd93942323e2

讓我們看看在遷移過程中涉及到的一些東西。我們需要遷移一些客戶機運行的現狀,也就是不用翻譯任何關於內存區域的內容--整個客戶機。這個客戶機被遷移代碼當做一個模糊的東西,我們只是將這些內容送到目的地,這個區域在以上圖表中被標記爲灰色。

圖表中最左邊的部分,就是客戶機可見的設備狀態,通過QEMU發送協議的狀態。包括每一個暴露給客戶機的設備狀態。

最右邊部分的圖表是QEMU狀態,整個狀態不涉及遷移過程。但是在遷移開始之前將這個狀態設置正確很重要。在源主機和目的主機上的QEMU設置必須相同,這是通過在兩個主機上使用一條相似的QEMU命令行來實現的。由於QEMU命令行的多種選擇非常難以搞定,我們使用Libvirt替我們選擇正確的。Libvirt可以確保QEMU兩邊程序的遷移設置正確性。對於Red Hat Enterprise Linux,運行QEMU不是首選,甚至在一些新版本上都不支持,所以我們都是通過Libvirt來使用QEMU的。

我們將會在接下來的環節,介紹有關這三個部分的更詳細的內容。

遷移的正確配置

  • Shared storage共享存儲

  • NFS settings NFS設置

  • Host time sync主機時間同步

  • Can’t stress enough how important this is!這點非常重要

  • Network configuration網絡設置

  • Host CPU types主機CPU類型

  • Guest machine types客戶機類型

  • esp. if migrating across QEMU versions如果遷移要誇QEMU版本需要主機客戶機類型

  • ROM sizes ROM大小

從圖標的最右邊開始看,將源主機和目標主機的設置相同是遷移的成功的關鍵。看起來將兩臺VM設置相同很簡單,但實際上有些細節並不那麼顯而易見。

VM使用的存儲必須共享,對於源主機和目標主機都是可用的。同時,共享是如何實現的也很重要,例如,文件系統使用必須被設置成取消緩存功能(否則來自源主機的動態數據,在目標主機開始運行並訪問存儲前,可能不會讀寫到存儲中,導致客戶機看到損壞的數據。)

兩端服務器的時鐘時間必須匹配一致。這裏可以使用NTP協議。但是設置正確的時區以及確保兩端主機的時間是相同的,這兩點也是至關重要的。我們在遷移初始成功的時候,已經有了幾個錯誤報告,而後期客戶機會變得遲鈍,或者完全停止運行。這個時候,很難在主機的時間間隔解決掉這個問題。對於這種錯誤設置,客戶機會毫無抵抗能力。

兩端主機的網絡設置必須匹配一致。如果客戶機之前在和其他服務器通話,那麼對那些服務器的訪問要在遷移後進行。防火牆設置在這裏也同樣重要。同時,在遷移過程中最好將存儲網絡和網絡分開。帶寬可用的情況下遷移會快很多,所以存儲IO讀寫最好不佔用網絡。

主機CPU類型必須一致。暴露給源主機客戶機的指令組必須對目標主機客戶機完全可用。這意味着從新一代處理器遷移到舊一代處理器可能不成功,除非非常小心啓動帶有首先指令組的VM。初始階段,操作系統(還有一些應用也是一樣)會向CPU詢問CPU支持的指令。然後必要時,他們會使用所有可用的指令。因此,要非常小心選擇暴露給客戶機的CPU型號。

QEMU可以支持暴露給客戶機的集中虛機類型。這是由大量的兼容性代碼組成的,這些代碼支持多種暴露給客戶機的設備。保持QEMU的bug修正和特徵的持續改進是必要的,因爲保持與以前QEMU版本的bug兼容性可以確保遷移持續進行。版本管理的另外一方面,就是多個ROM版本,通過QEMU設置來保證對客戶機可用,例如BIOS, iPXE ROMs等。這些ROM一定要在源主機和目標主機上都兼容。

在線遷移的階段

  • Live migration happens in 3 stages 在線遷移分3個階段

  • Stage 1: Mark all RAM dirty 第一個階段:將所有RAM都標記髒

  • Stage 2: Keep sending dirty RAM pages since last iteration 第二個階段:持續不斷髮送髒RAM

  • stop when some low watermark or condition reached

  • 當達到一些低水印或者條件時停止

  • Stage 3: Stop guest, transfer remaining dirty RAM, device state

  • Continue execution on destination qemu

  • 第三個階段:停止運行客戶機,將剩餘髒RAM,設備狀態轉移過去

  • 在目標主機QEMU上執行

我們來討論真實的遷移過程。這個部分指的是以上圖表中中間和最左邊部分。這個遷移過程分三個階段進行。前兩階段處理圖表中灰色區域,最後一個階段灰色區域和最左邊區域同時工作。

我們從第一階段開始,將灰色區域每一頁標記“髒頁面”或者“需要被遷移”。然後我們將所有標記爲髒頁面的發送給目標主機,這就是第一步。

記住一件事,我們前面指出,KVM爲用戶空間提供什麼服務?用戶空間的能力,例如QEMU,也就是找出最後一次數據被請求過的更改過的頁面能力。正是這樣,我們才能持續不斷髮送自上次迭代後那些經過客戶機更改過的頁面。

這就是第二階段。我們會一直停留在這個階段直到達到某個條件。我們隨後將會討論這些條件。在此指出,這個階段就是整個在線遷移過程最耗費時間的階段。

第三個階段就是過渡到非在線或者離線狀態遷移。實際上客戶機是暫停的,不再進行任何行動。然後我們將所有剩餘髒RAM和設備狀態轉移過去,這些設備狀態也就是圖表中最左邊區域。

灰色區域對於QEMU就是不透明數據,也要轉移過去。這個設備狀態是通過QEMU的特殊代碼處理,稍後討論這點。

在線遷移狀態

  • Live migration happens in 3 stages 在線遷移分3個階段

  • Stage 1: Mark all RAM dirty <ram_save_setup()>第一個階段:將所有RAM都標記髒

  • Stage 2: Keep sending dirty RAM pages since last iteration <ram_save_iterate()>第二個階段:持續不斷髮送髒RAM

  • stop when some low watermark or condition reached當達到一些低水印或者條件時停止

  • Stage 3: Stop guest, transfer remaining dirty RAM, device state <migration_thread()>第三個階段:停止運行客戶機,將剩餘髒RAM,設備狀態轉移過去

  • Continue execution on destination qemu在目標主機QEMU上執行

控制每個遷移階段的QEMU源代碼功能名稱會在以上圖表中藍色區域提及到,“遷移線程”功能是控制整個遷移過程,並且可以調用其他功能,所以我們從這開始理解整個遷移代碼。

EndingStage 2 (or Transitioning from Live to Offline State)

  • Earlier之前

  • 50 or fewer dirty pages left to migrate 50個或者更少的髒頁面等待遷移

  • no progress for 2 iterations沒有2次迭代過程

  • 30 iterations elapsed 30個迭代消逝

  • Now當前

  • admin-configurable downtime (for guests)客戶機admin-configurable故障時間

  • involves knowing # of pages left and bandwidth available包括瞭解髒頁面剩餘數量和可用帶寬

  • host policies: like host has to go down in 5 mins, migrate all VMs away within that time主機策略:如果主機要在五分鐘內停機,就要將所有VM在這個時間內遷移完成。

當從第二階段到到第三階段過渡時,要做一個很重要的決策:客戶機在第三階段會暫停運行,所以在第三階段要儘可能的將少遷移頁面,來減少停機時間。

QEMU的第一次遷移實施是很簡單的:如果在第二階段有50個或者更少的剩餘髒頁面需要遷移,將會過渡到第三階段。或者當一個特定數量的迭代消逝,且不再有任何程序遷移少於50個髒頁面,也會出現如上情況。

開始可能正常運行,但是隨後就會出現一些新的限制。用戶在KVM上運行負載時,做遷移必須要提供一些SLA,包括最大可接受停機時間等。所以我們要增加一些可調代碼,以便達到客戶機和主機都接受的從第二階段過渡到第三階段的條件。

客戶機管理可以具體闡述最大可接受的停機時間。在第二階段代碼,我們會在每個迭代來檢查有多少頁面被客戶機標記髒。會檢查花費多長時間來轉換一個頁面,以便來設定一個預估的網絡帶寬。在這個預估帶寬和當前迭代的髒頁面數量,我們可以計算出花費多久來轉化剩餘頁面。如果在可接受或者設置的停機時間限制內,我們過渡到第三階段是沒有問題的。否則我們會繼續停留在第二階段。當然,還有其他的一些可調的因素會不斷地讓我們停留在第二階段。

也有一些主機管理的設置可調因素。曾在2013年KVM論壇上,一個日本客戶在一個座談會上展示了一個很有意思的用例,這個用例描述了這個可調因素的必要性。日本數據中心接到地震警告,在這種情況下,數據中心會在一段時間內斷電,大約從警告開始的30分鐘內。服務提供者質優這30分鐘將所有的VM從一個數據中心遷移到另外一個。否則所有的VM都將因爲斷電而宕機。在這種情況下,客戶機SLA優先級下降。

QEMU的其他遷移代碼

  • General code that transmits data遷移數據的總代碼

  • tcp, unix, fd, exec, rdma

  • Code that serializes data使數據序列化的代碼

  • section start / stop

  • Device state設備狀態

QEMU中還有更多的與遷移有關的代碼:有些代碼是用來發送/接受遷移數據:TCP或者UNIX包,本地文件說明符,或者RDMA。也有exec功能,來自QEMU的數據,在被髮送到目的地前,會被傳輸到其他進程。這對於傳出數據壓縮,加密都很有用。在目的端,也需要進行解壓縮或者解加密進程。對於UNIX包,fd或者exec-based協議,需要更高層的程序來管理兩端的遷移。Libvirt就是這個程序,我們可以依賴libvirt的能力來控制這個遷移。

當然也有與數據序列化相關的代碼,這些代碼可以指示頁面何時何地開始,暫停等等。

也有與設備相關的代碼,接下來我們要討論到。

VMState

  • Descriptive device state描述性設備狀態

  • Each device does not need boilerplate code每一個設備不需要樣本文件代碼

  • Each device does not need identical save and load code每個設備不需要完全相同的保留和加載代碼

  • Which is easy to get wrong這樣容易出現錯誤。

設備狀態,在以上圖標中最左邊區域,對每一個設備都會有詳細的介紹。這個塊設備將列出清單,計算仍需要被磁盤擦掉的動態數據。同時,這個狀態的一部分就是客戶機配置或者選擇使用這個設備動作。網絡設備也有自己的狀態。幾乎所有的設備都暴露給客戶機,都有需要被遷移的狀態。這個設備狀態的遷移在第三個階段發生,也就是在所有髒RAM傳送結束之後。

每一個設備都必須控制好發送或者接收自己狀態。這意味着有很多圍繞QEMU所有設備的代碼副本。VMstate就是一個新被添加的基礎設施,將發送和接收部分的設備孤立出來。下面將用一個例子解釋。

VMStateExampleVMState例子

  • e1000 device e1000設備

  • e482dc3ea e1000: port to vmstate

  • 1 file changed,

  • 81 insertions(+),

  • 163 deletions(-)

將e1000設備從舊的處理狀態做遷移,轉換到VMState。需要插入81條命令,刪除163條。這樣就成功了。

VMStateExample (before)之前

-static void
-nic_save(QEMUFile *f, void *opaque)
{
 E1000State *s = opaque;
 inti;

 pci_device_save(&s->dev, f);
 qemu_put_be32(f, 0);
 qemu_put_be32s(f, &s->rxbuf_size);
 qemu_put_be32s(f, &s->rxbuf_min_shift);

這是一個命令執行部分,涉及到以上所說的舊代碼移除。這個nic_save()功能是“保留”——傳送中——在目的端需要所有的狀態都能正確操作,獨立地傳送每一個條目狀態。在此我們看到了32位整數結構的被傳送。

與nic_load()相對應的功能會按照相同的次序加載這個狀態。

很容易看到如何出錯,哪些副本對於設備是不必須的。同時,開發者們一點也不喜歡這樣寫代碼。

VMStateExample (after)之後

+static constVMStateDescription vmstate_e1000 = {
+ .name = "e1000",
+ .version_id = 2,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_PCI_DEVICE(dev, E1000State),
+ VMSTATE_UNUSED_TEST(is_version_1, 4), /* was instance id */
+ VMSTATE_UNUSED(4), /* Was mmio_base. */
+ VMSTATE_UINT32(rxbuf_size, E1000State),
+ VMSTATE_UINT32(rxbuf_min_shift, E1000State),

我們看到命令執行後的一部分代碼,添加了新的VMState方式,保留和修復設備狀態。這只是一個描述性的結構,來描述設備狀態的組成。所有樣本文件代碼在其他地方處理過,都顯而易見地添加到每一個設備上。

UpdatingDevices更新設備

  • Sometimes devices get migration-breaking changes有時設備會破壞性遷移改變

  • One idea is to bump up version number增加新版本號

  • Adds dependencies from higher versions to lower ones在低版本上依次添加高版本號

  • Difficult to cherry-pick fixes to stable / downstreams很難擇優選擇修復

  • Another is to introduce new subsection另一個是介紹新的小節

作爲規律的開發過程,會發現bug並修復它,新特徵也是這樣添加的。當設備狀態有了新變化,很多因素都要考慮到,來保持遷移後的兼容性。也就是,從老QEMU版本遷移過來的在新QEMU版本上運行的兼容性。新QEMU版本應該繼續接受即將從老的QEMU版本遷移過來的數據流。儘管狀態改變了。

控制好這樣的變化的一個典型的辦法就是靠給每一個設備進行版本控制,傳送過程中就改好版本。源QEMU不需要擔心目的端運行什麼版本。這隻取決於目的端QEMU來翻譯傳送過來的各種格式。

與目的端QEMU同樣的加載功能是,檢查傳送過來的是什麼版本的設備狀態。依賴版本管理,傳過來的數據被存儲到目的端設備結構的相應狀態變量中。這意味着,所有版本相關的複雜事務,都會存在遷移過程的目的端。

當然,目的端比源QEMU更低版本的QEMU不會知道傳送過來的數據,遷移過程在這種情況下會失敗。

但是這種版本管理機制有一個問題:試想版本2的e1000設備狀態。現在我們添加一個新特徵,需要給狀態再添加一些東西,變爲版本3.如果我們在版本2的狀態中檢測到一個bug,我們會修復它,更新到版本4。然而,修復後變爲穩定版本發行出來,或者不想發行新特徵,但是想要補丁修復就難了。沒有辦法補丁修復,並且保持與上一個版本號的連續性。變爲版本4不正確,因爲版本3還沒打補丁。

需要一個新的機制來解決這個困境,下一節將會講到,讓我們來看一個例子。

SubsectionExample

  • commit c2c0014 pic_common: migrate missing fields執行c2c0014 pic_common:遷移丟失的區域。

VMSTATE_INT64(timer_expiry,
APICCommonState), /* open-coded timer state */
VMSTATE_END_OF_LIST()
+ },
+ .subsections = (VMStateSubsection[]) {
+ {
+ .vmsd = &vmstate_apic_common_sipi,
+ .needed = apic_common_sipi_needed,
+ },
+ VMSTATE_END_OF_LIST()
}
};

我們看到一個新部分添加到apic代碼的vmstate數據中。這個所需功能會在源端評估。如果結果是真的(也就是客戶機處於那一小部分需要被傳到目的端的狀態)在vmsd部分中vmstate信息將被傳送到目的端。

這個消除版本管理的需要,最優選擇更簡單些,並且能在多個QEMU版本中兼容。

最近變化

  • Guests have grown bigger客戶機變大

  • More RAM更大RAM

  • Means a lot of time spent transferring pages意味着要花費更多時間傳輸頁面

  • More


  • vCPUs更多vCPU


  • Means active guests keep dirtying pages意味着運行中的客戶機要不斷保持標記髒頁面

現在我們討論一下QEMU在遷移代碼中如何運行。KVM已經成熟了,更多地客戶用它在他們的KVM虛擬化層來處理企業加載。我們看到更大的客戶機:分配更多RAM,更多的vCPU暴露給客戶機。大RAM客戶機意味着有更多的數據會在第二階段被傳送,反過來,意味着隨之而來的停機時間要求變得更加困難實現。更多vCPU意味着客戶機要做更多的工作,更多的RAM區域要被標記髒,導致第二階段時間變長。

QEMU最近的一些新特徵消失了,有助於以下這些情況:

NewFeatures新特徵

  • Autoconverge自動匯聚

  • xbzrle

  • migration bitmap

  • migration thread遷移線程


  • rdma

  • block migration塊存儲遷移

自動匯聚:這個設置可以暫停一些vCPU,通過降低遷移速度,客戶機在第二遷移階段不會進行太多過程。這樣就給一些髒頁面機會,來減少我們過渡到第三階段的低水印條件。暫停客戶機vCPU可以有幾種方式:重新啓動主機客戶機線程(每一個vCPU在主機就是一個線程)或者限制主機CPU時間,或者在QEMU代碼中不將客戶機vCPU列入計劃。

Xbzrle:這個特徵是將上一個迭代的所有發到目的端的頁面進行緩存。對於每一個被髮送的頁面,我們將當前頁面與緩存頁面做比較,只有在頁面比較出來不同的字節才被髮送過去。這樣能夠很大程度地減少佔用網絡負載的數據量,可以加速遷移過程。

遷移線程:起初,QEMU代碼爲QEMU所有活動只佔用一個線程,爲客戶機vCPU分配其他線程。這意味着任何QEMU任何一個活動都會阻礙其他活動進行。在遷移用例中,當發送和接收數據時,QEMU的其他活動都無法進行,這也意味着與QEMU交互的應用不能查詢QEMU遷移進行到什麼程度了。缺少報告對於管理來說體驗很不好,也就是說要在第二階段等上一個迭代結束後,才能知道這個過程是不是完成了。將遷移代碼分配到與之配備的線程上,QEMU在這個遷移線程上運行,這樣可以減少瓶頸了。

遷移:一個字節過去用來追蹤一個髒頁面。對於大RAM客戶機來說,意味着位圖會變得很大,甚至比CPU緩存更大,第二階段的每個迭代的頁面操作都會變得很慢。另一個缺點就是當主機在低內存時進行遷移,由於要給遷移元數據分配更多的RAM,導致主機運行更慢。我們現在使用一個比特代表每一個客戶機頁面,減少髒頁面位圖,這樣CPU緩存也不會佔用很多,整個過程也不會很慢。

RDMA:使用像infiniband設備一樣,在源端和目的端主機的快速互聯,可以確保遷移數據比以太網傳送的更快。RDMA代碼還很新,沒有經歷過充分的測試,所以在這個領域,也有潛在貢獻者在尋找其他技術提升其性能。

塊存儲遷移:除了遷移這些狀態,一些客戶需要使用非共享塊存儲。這樣,存儲也要隨着主機狀態一起被遷移。塊數據很大,要在網絡帶寬和需要遷移的時間上花費很大代價。

Stuffthat’s lined up

  • postcopy預先拷貝

  • debuggability排障能力

遷移代碼中有很多正在進行的任務,其中一個就是預先拷貝,這樣會使遷移停機時間變得非常短。

我們之前描述的遷移過程就是預先拷貝模型。在切換到目的端客戶機運行之前,所有數據先拷貝到目的端主機。在預先拷貝模型中,要盡塊切換到目的端,這意味着我們要將設備狀態,一個迭代髒RAM傳送過去,然後切換到運行目的端。當客戶機引用這個RAM的某些頁面,而這個頁面在目的端不存在,遠程頁面容錯會從源主機中把頁面抓取過來傳送到目的端。這樣會很容易理解爲什麼這個方法在聚合速度上很快。當然,也會引起其他的一些錯誤:如果一個主機壞掉,或者兩個主機之間的網絡連接斷掉,整個客戶機就會丟失,兩個主機就不會再通信了。對於預先拷貝文件機制,源主機的丟失,意味着客戶機永遠丟失。

遷移過程的排障能力不是很好:有線格式描述很差,遷移失敗會給出這樣的信息“設備加載失敗,遷移失敗”不會給出有關設備加載失敗的位置和原因。潛在貢獻者可以找到一些技術將這個優化的更好些,這也是一個學習代碼的好機會。

Futurework未來任務

  • Finish vmstate conversion完成vmstate轉換

  • self-describing wire format有線格式自描述

像完成vmstate轉換這樣的任務還沒有人開始着手。不幸的是,不是所有的設備都轉化成vmstate。最大的一個就是virtio設備。這樣做很有必要,以便於所有的東西都有統一的代碼。也有一個檢查程序,來檢查不同QEMU版本之間的遷移兼容性。這種程序只以vmstate數據格式工作,而virtio設備目前還不能實現。

同時,如上一部分提到的,自描述功能的有線格式有助於排障,也有助於監控各種抵消掉的數據流等等。這個目前還不可能實現。

這只是QEMU-KVM虛機在線遷移的概覽。QEMU歸檔清單裏有幾個細節,包括各種優化性能指標,以及一些各自指標的特徵討論。在以下章節我們會繼續討論到。


歡迎加我微信(ID:xiaolikvm)一起交流。歡迎加入雲技術社區KVM/QEMU技術交流QQ,請加QQ:502207183,註明姓名,城市,及要加入KVM羣。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章