掃二維碼與項目經理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流
2023-08-07 14:28:42
云計算 借助實時遷移技術,Linode 實例可在不中斷服務的前提下在不同物理服務器之間移動。通過實時遷移工具移動 Linode 實例時,遷移過程對 Linode 實例中運行的進程是完全不可見的。這幾乎成為一種決定性的技術,也成為云技術和非云技術之間的轉折點。本文我們將深入了解這項技術背后的細節(jié)。?

成都創(chuàng)新互聯(lián)公司主營頭屯河網(wǎng)站建設的網(wǎng)絡公司,主營網(wǎng)站建設方案,手機APP定制開發(fā),頭屯河h5微信小程序開發(fā)搭建,頭屯河網(wǎng)站營銷推廣歡迎頭屯河等地區(qū)企業(yè)咨詢
當開發(fā)者將工作負載部署到云計算平臺時,往往并不需要考慮運行這些服務的底層硬件。在人們對“云” 的理想化印象中,硬件維護和物理限制往往是無形的,然而硬件不可避免需要時不時進行維護,這可能會導致停機。為避免這樣的停機時間被轉嫁給我們的客戶,并真正實現(xiàn)云的承諾,Linode 提供了一種名為實時遷移(Live Migration)的工具。
借助實時遷移技術,Linode 實例可在不中斷服務的前提下在不同物理服務器之間移動。通過實時遷移工具移動 Linode 實例時,遷移過程對 Linode 實例中運行的進程是完全不可見的。如果一臺主機的硬件需要維護,即可通過實時遷移,將該主機上的所有 Linode 實例無縫轉移到另一臺主機中。遷移操作完成后,即可開始修理物理硬件,全過程中并不產生會影響到客戶的停機時間。
這幾乎成為一種決定性的技術,也成為云技術和非云技術之間的轉折點。本文我們將深入了解這項技術背后的細節(jié)。
為慶祝 Linode 加入 Akamai 解決方案大家庭,現(xiàn)在注冊 Linode,就可免費獲得價值 100 美元的使用額度,可以隨意使用 Linode 云平臺提供的各種服務。立即點擊這里了解詳情并注冊吧↓↓↓
出海云服務,Akamai 是您的不二之選!
和大部分新項目類似,Linode 的實時遷移也是這樣啟動的:進行大量研究,創(chuàng)建一系列原型,獲得同事和管理層的大量幫助。我們的第一步是調查 QEMU 如何處理實時遷移。QEMU 是 Linode 使用的一種虛擬化技術,而實時遷移也是 QEUM 的一項功能。因此我們團隊的重點是將這項技術引入 Linode,而非重新發(fā)明一個類似的技術。
那么實時遷移技術到底是如何以 QEMU 的方式實現(xiàn)的?整個過程分為以下四步:
這些步驟概括介紹了 QEMU 實時遷移的執(zhí)行過程。然而依然需要通過包含很多手工操作的方式來精確指定目標 QEMU 實例的啟動方式。此外,上述過程中的每個操作都必須在正確的時間執(zhí)行。
在分析過 QEMU 開發(fā)者已經實現(xiàn)的技術后,我們該考慮具體用怎樣的方式將其實給 Linode。這個答案恰恰是我們工作的重中之重。
在實時遷移工作流程的第 1 步,需要啟動目標 QEMU 實例以接受傳入的實施遷移連接。在實現(xiàn)這一步時,我們最初的想法是拿到當前 Linode 實例的配置文件,隨后將其應用到目標計算機。理論上這應該很簡單,但進一步思考就會發(fā)現(xiàn),實際情況要復雜很多。尤其是,配置文件雖然可以告訴我們 Linode 實例是如何啟動的,但并不一定可以完整描述啟動后的 Linode 實例的完整狀態(tài)。例如,用戶可以在 Linode 實例啟動完畢后通過熱插拔的方式連接塊存儲設備,但這種情況并不會記錄到配置文件中。
為了在目標主機上創(chuàng)建 QEMU 實例,必須對當前運行的 QEMU 實例進行剖析。我們通過檢查 QMP 接口的方式對運行中的 QEMU 實例進行剖析,該接口為我們提供了與 QEMU 實例布局情況有關的豐富信息,但它無法幫助我們從來賓系統(tǒng)的視角了解實例內部正在發(fā)生的事情。例如,對于本地 SSD 和塊存儲,它只能告訴我們磁盤鏈接到哪里,以及虛擬磁盤連接到哪個虛擬化 PCI 插槽上。在查詢 QMP 以及檢查并分析了 QEMU 接口后,可以構建一個 Profile 來描述如何在目標位置創(chuàng)建一個完全相同的實例。
在目標計算機上,我們將收到完整的描述信息,借此了解源實例到底是什么樣,隨后就可以在目標位置忠實重建這個實例,但此時還有一個差異。這個差別主要在于,目標 QEMU 實例在啟動時使用了一個選項,該選項可以讓 QEMU 接受傳入的遷移。
至此,實時遷移的記錄過程已經基本結束,接下來需要看看 QEMU 是如何實現(xiàn)這些操作的。QEMU 進程樹由一個控制進程和多個工作進程組成,其中一個工作進程負責返回 QMP 調用或處理實時遷移等任務,其他進程需要一對一映射至來賓 CPU。來賓環(huán)境與 QEMU 端的功能相互隔離,具體行為類似于獨立的系統(tǒng)。
從這個意義來看,我們需要處理三層內容:
目標實例啟動并準備好接受傳入的遷移后,目標硬件會告知源硬件開始發(fā)送數(shù)據(jù)。源端會在收到這個信號后開始進行處理,并會在軟件中告知 QEMU 開始傳輸磁盤內容。軟件會自主監(jiān)控磁盤傳輸進度,借此檢查傳輸操作是否完成,并會在磁盤傳輸完成后自動開始遷移內存內容。此時軟件依然會自主監(jiān)控內存遷移進度,并在內存遷移完畢后自動切換至割接模式。上述全過程都是通過 Linode 的 40Gbps 網(wǎng)絡進行的,因此網(wǎng)絡方面的操作都可以快速完成。
割接操作是實時遷移過程中最重要的一環(huán),只有理解了它,才能完全理解實時遷移操作。
在割接點狀態(tài)下,QEMU 已經確認做好了所有準備,可以進行割接并在目標計算機上運行。源 QEMU 實例會讓兩端暫停運行,這意味著:
由于時間和網(wǎng)絡請求均已停止,我們希望割接能盡量快速完成。然而為保證成功割接,還需要進行一些檢查:
由于割接過程時間有限,我們希望能盡快完成上述操作。解決了這些問題后,即可繼續(xù)進行割接了。源 Linode 實例會自動會自動收到 “割接完成” 信號并讓目標實例運行起來。目標 Linode 實例會從源實例暫停時的狀態(tài)恢復運行。源和目標實例上的其余內容則會被清理。如果目標 Linode 實例在未來某個時間需要再次進行實時遷移,則會重復執(zhí)行上述步驟。
實時遷移的大部分過程都是直接實現(xiàn)的,但考慮到邊緣案例后,該功能本身的開發(fā)也進行了大量擴展。這個項目的順利完成很大程度上要歸功于管理團隊,他們堅信該工具有著極大的愿景,并提供了完成該任務所需的各項資源,另外當然也離不開堅信該項目能夠成功完成的大量員工。
我們在下列這些領域遇到了很多邊緣案例:
在向來賓操作系統(tǒng)呈現(xiàn) CPU 方面,QEMU 有不同的選項。其中一個選項可將主機 CPU 的型號和功能(即 CPU 標記)直接傳遞給來賓系統(tǒng)。通過使用該選項,來賓即可不受約束地使用 KVM 虛擬化系統(tǒng)所支持的全部能力。當 Linode 首次采用 KVM 時(當時還沒有實時遷移功能),為了實現(xiàn)最大化性能,我們就使用了該選項。然而在開發(fā)實時遷移功能的過程中,該選項為我們造成了很多挑戰(zhàn)。
在實時遷移的測試環(huán)境中,源和目標主機是兩臺完全相同的計算機。但在現(xiàn)實世界中,我們的硬件集群并非 100% 完全相同的,計算機之間的某些配置差異可能導致產生不同的 CPU 標記。這很重要,因為當一個程序被載入 Linode 的操作系統(tǒng)后,Linode 會向該程序呈現(xiàn) CPU 標記,為了充分利用這些標記,程序可以將軟件中的特定部分載入內存。如果一個 Linode 實例被實時遷移到不支持該 CPU 標記的目標計算機,程序將會崩潰。這可能導致來賓操作系統(tǒng)崩潰,甚至導致 Linode 重啟動。
我們發(fā)現(xiàn)有三個因素會影響到計算機的 CPU 標記如何呈現(xiàn)給來賓系統(tǒng):
因此在實現(xiàn)實時遷移時,我們必須設法防止程序因為 CPU 標記的不匹配而崩潰。可行的選項有兩個:
在決定對源和目標的 CPU 標記進行匹配后,我們使用下列兩種方法的組合最終實現(xiàn)了目標:
第二種方法必須能快速執(zhí)行,并且讓我們的工作變得更復雜。某些情況下,我們需要針對超過 900 臺計算機檢查最多 226 個 CPU 標記。為所有這 226 個 CPU 標記編寫檢查代碼本就很困難,而這些代碼還需要不斷進行維護。但 Linode 的創(chuàng)始人 Chris Aker 提出的一個驚人想法最終解決了這個問題。
方法的關鍵在于為所有 CPU 標記創(chuàng)建一個列表,并將其表示為一個二進制字符串。隨后,可以使用 Bitwise and(“按位與”)運算來對比字符串。我們可以用下面這個簡單的例子來演示這個算法。下面這段 Python 代碼可以使用 “按位與” 對比兩個數(shù):
>>> 1 & 1
1
>>> 2 & 3
2
>>> 1 & 3
1要理解為何“按位與” 運算能產生這樣的結果,首先需要將數(shù)字用二進制形式表示。一起看看十進制的“2” 和“3” 在用二進制形式表示的情況下,“按位與” 是如何處理的:
>>> # 2: 00000010
>>> # &
>>> # 3: 00000011
>>> # =
>>> # 2: 00000010“按位與” 會對比二進制的“數(shù)”,也就是兩個不同數(shù)字中的“位”。該操作會從上述數(shù)字最右邊的位開始向左處理:
因此完整結果的二進制表示就是 00000010,也就是十進制的 “2”。
對于實時遷移,CPU 標記完整列表會表示為一個二進制字符串,其中每一位都代表一個標記。如果一個位為 “0”,代表對應的標記不存在;如果某個位為“1”,則代表標記存在。例如,一個位可以代表 AES 標記,另一個位可以代表 MMX 標記。這些標記在二進制字符串中的位置會維護并記錄在案,隨后用于我們數(shù)據(jù)中心內的所有計算機。
相比維護一組 if 語句來檢查某個 CPU 標記是否存在,這種列表的維護工作無疑更簡單也更高效。例如,假設總共需要追蹤并檢查 7 個 CPU 標記,這些標記可以存儲在一個 8 位數(shù)字中(多出的一位供未來進行擴展)。例如這樣的字符串可能類似于 00111011,最右側的一位代表 AES 已啟用,右數(shù)第二位代表 MMX 已啟用,右數(shù)第三位代表其他標記已啟用,以此類推。
在下文的代碼片段中,我們可以看到哪些硬件支持這些標記的組合,這段代碼可以在一個周期內返回所有匹配的結果。如果用一組 if 語句進行對比,則需要更多周期才能獲得所需結果。如果進行實時遷移的源計算機包含 4 個 CPU 標記,這種情況下就需要 203400 個周期才能找到匹配的硬件。
實時遷移操作會在源和目標計算機上針對 CPU 標記字符串執(zhí)行 “按位與” 操作。如果兩個計算機的 CPU 標記字符串運算結果相等,意味著目標計算機是兼容的。該過程可參考下列 Python 代碼片段:
>>> # The b'' syntax below represents a binary string
>>>
>>> # The s variable stores the example CPU flag
>>> # string for the source:
>>> s = b'00111011'
>>> # The source CPU flag string is equivalent to the number 59:
>>> int(s.decode(), 2)
59
>>>
>>> # The d variable stores the example CPU flag
>>> # string for the source:
>>> d = b'00111111
>>> # The destination CPU flag string is equivalent to the number 63:
>>> int(d.decode(), 2)
63
>>>
>>> # The bitwise and operation compares these two numbers:
>>> int(s.decode(), 2) & int(d.decode(), 2) == int(s.decode(), 2)
True
>>> # The previous statement was equivalent to 59 & 63 == 59.
>>>
>>> # Because source & destination == source,
>>> # the machines are compatible請注意,在上述代碼片段中,目標計算機比源計算機支持更多的標記。此時可以認為目標計算機是兼容的,因為源的所有 CPU 標記都已包含在目標計算機中,這一點可以由 “按位與” 運算提供保證。
我們的內部工具可以使用上述算法得到的結果為可兼容的硬件構建一個列表。該列表會展示給我們的客戶支持和硬件運維團隊,這些團隊可以使用我們的內部工具來編排不同的運維任務:
僅僅為了讓軟件能夠“跑起來”,就需要進行大量的開發(fā)工作……
軟件領域有一個話題很少被人討論:優(yōu)雅地處理失敗。軟件至少應該能夠“跑起來”。為了實現(xiàn)這一點,往往需要進行大量開發(fā)工作,實時遷移功能的開發(fā)也是如此。我們花了很多時間考慮如果該工具無法正常運行要怎么辦,以及該如何優(yōu)雅地處理這種情況。我們考慮了很多場景,并確定了具體的應對方式:
o 解決方法:客戶完全可以這樣做。實時遷移會被打斷,無法繼續(xù)處理。這種處理方法是合適的,因為實時遷移可以稍后重試。
o 解決方法:通知源硬件,通過專門設計的內部工具在數(shù)據(jù)中心內自動選擇另一個硬件。此外還將通知運維團隊,以便調查失敗的目標硬件。這種情況曾在生產環(huán)境中發(fā)生過,我們的實時遷移可以順利應對。
o 解決方法:自主監(jiān)測實時遷移進度,如果過去一分鐘內沒有產生任何進展,將會取消實時遷移并通知運維團隊。這種情況在測試環(huán)境之外從未發(fā)生過,但我們也針對這種場景做好了充分準備。
o解決方法:如果實時遷移未進行到關鍵環(huán)節(jié),將停止實時遷移,并在稍后重試。
o如果已進行到關鍵環(huán)節(jié),則將繼續(xù)遷移。這一點很重要,因為源 Linode 已被暫停,目標 Linode 需要處于啟動狀態(tài)才能繼續(xù)恢復操作。
這些場景都已在測試環(huán)境中進行了模擬,我們認為上述行為也是不同情況下的最佳應對措施。
成功進行了數(shù)十萬次實時遷移后,我們不免會考慮:“實時遷移的開發(fā)工作何時才能結束?” 隨著時間推移,實時遷移這項技術的使用范圍會越來越廣,并且會不斷完善,因此該項目似乎會永遠持續(xù)下去?;卮疬@個問題的一種方法是考慮該項目的大部分工作什么時候會結束。答案也很簡單:為了獲得可靠、可信賴的軟件,我們的工作還將持續(xù)很久。
隨著時間推移,Linode 會增加新的功能,我們也許要繼續(xù)努力保證實時遷移可以兼容這些功能。引入某些新功能時,可能無需圍繞實時遷移執(zhí)行新的開發(fā)工作,但我們可能依然需要測試該功能是否可以按照預期正常工作。對于某些功能,則可能需要在開發(fā)的早期階段,針對實時遷移進行必要的兼容性測試和相關工作。
和其他幾乎所有軟件類似,對于同一件事,通過不斷研究,總能發(fā)現(xiàn)更好的實現(xiàn)方法。例如,從長遠來看,為實時遷移功能開發(fā)更多模塊化的集成方法,無疑可以降低維護負擔?;蛘呶覀兩踔量赡軐崟r遷移的相關功能納入到底層代碼中,從而使其成為 Linode 一項拆箱即用的功能。
我們的團隊已經考慮過所有這些選項,并且堅信驅動 Linode 平臺的工具是活躍的,還會繼續(xù)努力,使其不斷進化和發(fā)展。
這篇文章的內容感覺還行吧?有沒有想要立即在 Linode 平臺上親自嘗試一下?別忘了,現(xiàn)在注冊可以免費獲得價值 100 美元的使用額度,快點自己動手體驗本文介紹的功能和服務吧↓↓↓
出海云服務,Akamai 是您的不二之選!
歡迎關注 Akamai ,第一時間了解高可用的 MySQL/MariaDB 參考架構,以及豐富的應用程序示例。

我們在微信上24小時期待你的聲音
解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流