幫你降低成本的不停機(jī)實(shí)時(shí)遷移,技術(shù)上到底是怎么做到的?
云計(jì)算幫助用戶降低成本的方法有很多,不過(guò)有一點(diǎn)可能被很多人忽略了,那就是不停機(jī)實(shí)時(shí)遷移(Live Migration)。
延伸閱讀,點(diǎn)擊鏈接了解Akamai Cloud Computing
實(shí)時(shí)遷移如何幫助我們降低成本?那花樣可就多了:
- 資源動(dòng)態(tài)調(diào)整:借助實(shí)時(shí)遷移功能,在不中斷服務(wù)的情況下將工作負(fù)載從一個(gè)實(shí)例遷移到另一個(gè)實(shí)例,從而根據(jù)需求動(dòng)態(tài)調(diào)整資源。例如,在低峰期間,可以將工作負(fù)載從高性能實(shí)例遷移到低成本實(shí)例,以節(jié)省成本;在高峰期間則可以遷移回高性能實(shí)例以應(yīng)對(duì)需求。
- 故障恢復(fù)和容災(zāi):實(shí)時(shí)遷移功能可以幫我們快速將工作負(fù)載遷移到備用實(shí)例,以應(yīng)對(duì)主機(jī)故障或區(qū)域性故障。通過(guò)實(shí)時(shí)遷移,可以確保服務(wù)的持續(xù)可用性,減少停機(jī)時(shí)間和業(yè)務(wù)影響,同時(shí)降低成本,因?yàn)閭溆脤?shí)例通常會(huì)配置為低成本的冷備份。
- 定期維護(hù):云服務(wù)提供商會(huì)定期進(jìn)行基礎(chǔ)設(shè)施維護(hù)和更新,這可能會(huì)導(dǎo)致一些短暫的服務(wù)中斷。通過(guò)實(shí)時(shí)遷移功能,我們可以在維護(hù)期間將工作負(fù)載遷移到其他實(shí)例,以確保服務(wù)的連續(xù)性,并避免因維護(hù)活動(dòng)而導(dǎo)致的潛在損失。
- 按需資源使用:實(shí)時(shí)遷移功能使我們能更靈活地管理資源使用情況,根據(jù)需要隨時(shí)調(diào)整實(shí)例規(guī)格和數(shù)量。根據(jù)實(shí)際需求動(dòng)態(tài)調(diào)整資源,可以避免過(guò)度配置實(shí)例,從而降低不必要的成本。
總的來(lái)說(shuō),通過(guò)云實(shí)例的實(shí)時(shí)遷移功能,用戶可以更靈活地管理和優(yōu)化資源使用,根據(jù)需求動(dòng)態(tài)調(diào)整實(shí)例配置,從而降低成本并提高服務(wù)的可用性和性能。
那么正在使用Linode云服務(wù)的你,是否考慮過(guò):這種聽起來(lái)很方便的實(shí)時(shí)遷移功能,從底層的技術(shù)上來(lái)看,到底是怎么實(shí)現(xiàn)的?本文我們將深入了解這項(xiàng)技術(shù)背后的細(xì)節(jié)。
實(shí)時(shí)遷移的工作原理
在開發(fā)這項(xiàng)功能時(shí),我們的第一步是調(diào)查QEMU如何處理實(shí)時(shí)遷移。QEMU是Linode使用的一種虛擬化技術(shù),而實(shí)時(shí)遷移也是QEUM的一項(xiàng)功能。因此我們的重點(diǎn)是將這項(xiàng)技術(shù)引入Linode,而非重新發(fā)明一個(gè)類似的技術(shù)。
那么實(shí)時(shí)遷移技術(shù)到底是如何以QEMU的方式實(shí)現(xiàn)的?整個(gè)過(guò)程分為以下四步:
1.啟動(dòng)目標(biāo)QEUM實(shí)例,該實(shí)例的各項(xiàng)參數(shù)與需要遷移的源QEUM實(shí)例完全相同。
2.對(duì)磁盤進(jìn)行實(shí)時(shí)遷移。數(shù)據(jù)傳輸過(guò)程中,對(duì)磁盤內(nèi)容進(jìn)行的任何更改也會(huì)提交至目標(biāo)磁盤。
3.對(duì)內(nèi)存數(shù)據(jù)進(jìn)行實(shí)時(shí)遷移。遷移過(guò)程中,內(nèi)存內(nèi)容的任何變化也會(huì)提交至目標(biāo)內(nèi)存。如果這一過(guò)程中磁盤內(nèi)容也出現(xiàn)了變化,相關(guān)變化同樣會(huì)被提交至目標(biāo)QEUM實(shí)例的磁盤中
4.執(zhí)行割接點(diǎn)。當(dāng)QEMU確認(rèn)有足夠多的內(nèi)存頁(yè)可以放心進(jìn)行割接后,源和目標(biāo)QEMU實(shí)例將會(huì)暫停。QEMU會(huì)復(fù)制最后幾頁(yè)內(nèi)存數(shù)據(jù)和機(jī)器狀態(tài),機(jī)器狀態(tài)包括CPU緩存和下一條CPU指令。隨后,QEMU會(huì)讓目標(biāo)開始運(yùn)行,這樣目標(biāo)實(shí)例就可以從源實(shí)例停止時(shí)的狀態(tài)恢復(fù)運(yùn)行了。
這些步驟概括介紹了QEMU實(shí)時(shí)遷移的執(zhí)行過(guò)程。然而依然需要通過(guò)包含很多手工操作的方式來(lái)精確指定目標(biāo)QEMU實(shí)例的啟動(dòng)方式。此外,上述過(guò)程中的每個(gè)操作都必須在正確的時(shí)間執(zhí)行。
Linode實(shí)現(xiàn)實(shí)時(shí)遷移的方式
在分析過(guò)QEMU已經(jīng)實(shí)現(xiàn)的技術(shù)后,我們?cè)摽紤]具體用怎樣的方式將其實(shí)施到Linode平臺(tái)上。
在實(shí)時(shí)遷移工作流程的第1步,需要啟動(dòng)目標(biāo)QEMU實(shí)例以接受傳入的實(shí)施遷移連接。在實(shí)現(xiàn)這一步時(shí),我們最初的想法是拿到當(dāng)前Linode實(shí)例的配置文件,隨后將其應(yīng)用到目標(biāo)計(jì)算機(jī)。理論上這應(yīng)該很簡(jiǎn)單,但進(jìn)一步思考就會(huì)發(fā)現(xiàn),實(shí)際情況要復(fù)雜很多。尤其是,配置文件雖然可以告訴我們Linode實(shí)例是如何啟動(dòng)的,但并不一定可以完整描述啟動(dòng)后的Linode實(shí)例的完整狀態(tài)。例如,用戶可以在Linode實(shí)例啟動(dòng)完畢后通過(guò)熱插拔的方式連接塊存儲(chǔ)設(shè)沒(méi)備,但這種情況并不會(huì)記錄到配置文件中。
為了在目標(biāo)主機(jī)上創(chuàng)建QEMU實(shí)例,必須對(duì)當(dāng)前運(yùn)行的QEMU實(shí)例進(jìn)行剖析。我們通過(guò)檢查QMP接口的方式對(duì)運(yùn)行中的QEMU實(shí)例進(jìn)行剖析,該接口為我們提供了與QEMU實(shí)例布局情況有關(guān)的豐富信息,但它無(wú)法幫助我們從來(lái)賓系統(tǒng)的視角了解實(shí)例內(nèi)部正在發(fā)生的事情。例如,對(duì)于本地SSD和塊存儲(chǔ),它只能告訴我們磁盤鏈接到哪里,以及虛擬磁盤連接到哪個(gè)虛擬化PCI插槽上。在查詢QMP以及檢查并分析了QEMU接口后,可以構(gòu)建一個(gè)Profile來(lái)描述如何在目標(biāo)位置創(chuàng)建一個(gè)完全相同的實(shí)例。
在目標(biāo)計(jì)算機(jī)上,我們將收到完整的描述信息,借此了解源實(shí)例到底是什么樣,隨后就可以在目標(biāo)位置忠實(shí)重建這個(gè)實(shí)例,但此時(shí)還有一個(gè)差異。這個(gè)差別主要在于,目標(biāo)QEMU實(shí)例在啟動(dòng)時(shí)使用了一個(gè)選項(xiàng),該選項(xiàng)可以讓QEMU接受傳入的遷移。
至此,實(shí)時(shí)遷移的記錄過(guò)程已經(jīng)基本結(jié)束,接下來(lái)需要看看QEMU是如何實(shí)現(xiàn)這些操作的。QEMU進(jìn)程樹由一個(gè)控制進(jìn)程和多個(gè)工作進(jìn)程組成,其中一個(gè)工作進(jìn)程負(fù)責(zé)返回QMP調(diào)用或處理實(shí)時(shí)遷移等任務(wù),其他進(jìn)程需要一對(duì)一映射至來(lái)賓CPU。來(lái)賓環(huán)境與QEMU端的功能相互隔離,具體行為類似于獨(dú)立的系統(tǒng)。
從這個(gè)意義來(lái)看,我們需要處理三層內(nèi)容:
第1層是管理層;
第2層是QEMU進(jìn)程的一部分,負(fù)責(zé)處理所有操作;
第3層是實(shí)際的來(lái)賓層,負(fù)責(zé)與Linode用戶進(jìn)行交互。
目標(biāo)實(shí)例啟動(dòng)并準(zhǔn)備好接受傳入的遷移后,目標(biāo)硬件會(huì)告知原硬件開始發(fā)送數(shù)據(jù)。源端會(huì)在收到這個(gè)信號(hào)后開始進(jìn)行處理,并會(huì)在軟件中告知QEMU開始傳輸磁盤內(nèi)容。軟件會(huì)自主監(jiān)控磁盤傳輸進(jìn)度,借此檢查傳輸操作是否完成,并會(huì)在磁盤傳輸完成后自動(dòng)開始遷移內(nèi)存內(nèi)容。此時(shí)軟件依然會(huì)自主監(jiān)控內(nèi)存遷移進(jìn)度,并在內(nèi)存遷移完畢后自動(dòng)切換至割接模式。上述全過(guò)程都是通過(guò)Linode的40Gbps網(wǎng)絡(luò)進(jìn)行的,因此網(wǎng)絡(luò)方面的操作都可以快速完成。
割接:關(guān)鍵環(huán)節(jié)
割接操作是實(shí)時(shí)遷移過(guò)程中最重要的一環(huán),只有理解了它,才能完全理解實(shí)時(shí)遷移操作。
在割接點(diǎn)狀態(tài)下,QEMU已經(jīng)確認(rèn)做好了所有準(zhǔn)備,可以進(jìn)行割接并在目標(biāo)計(jì)算機(jī)上運(yùn)行。源QEMU實(shí)例會(huì)讓兩端暫停運(yùn)行,這意味著:
1. 來(lái)賓系統(tǒng)被"時(shí)停"。如果來(lái)賓系統(tǒng)正在運(yùn)行時(shí)間同步服務(wù)(如NTP)NTP會(huì)在遷移完成后自動(dòng)重新同步時(shí)間。這是因?yàn)橄到y(tǒng)時(shí)鐘會(huì)產(chǎn)生幾秒鐘的落后。
2. 網(wǎng)絡(luò)請(qǐng)求停止。如果網(wǎng)絡(luò)請(qǐng)求是TCP請(qǐng)求(如SSH或HTTP),基本上不會(huì)產(chǎn)生可感知的連接中斷; 如果網(wǎng)絡(luò)請(qǐng)求是UDP請(qǐng)求(如流媒體視頻),可能會(huì)導(dǎo)致少量丟幀。
由于時(shí)間和網(wǎng)絡(luò)請(qǐng)求均已停止,我們希望割接能盡量快速完成。然而為保證成功割接,還需要進(jìn)行一些檢查:
- 確保實(shí)時(shí)遷移順利完成不出錯(cuò)。如果出錯(cuò)則要進(jìn)行回滾,解除源Linode實(shí)例的暫停狀態(tài),不再進(jìn)一步執(zhí)行其他操作。開發(fā)過(guò)程中,我們?cè)谶@方面進(jìn)行了大量實(shí)驗(yàn)并解決了很多錯(cuò)誤,雖然這為我們?cè)斐闪撕芏囝^疼的問(wèn)題,但最終都順利解決了。
- 確保關(guān)閉源實(shí)例的網(wǎng)絡(luò),并在目標(biāo)實(shí)例上正確連接。
- 讓我們的其余基礎(chǔ)設(shè)施清楚得知遷移后的Linode實(shí)例是通過(guò)哪臺(tái)物理計(jì)算機(jī)運(yùn)行的。
由于割接過(guò)程時(shí)間有限,我們希望能盡快完成上述操作。解決了這些問(wèn)題后,即可繼續(xù)進(jìn)行割接了。源Linode實(shí)例會(huì)自動(dòng)收到"割接完成"信號(hào)并讓目標(biāo)實(shí)例運(yùn)行起來(lái)。目標(biāo)Linode實(shí)例會(huì)從源實(shí)例暫停時(shí)的狀態(tài)恢復(fù)運(yùn)行。源和目標(biāo)實(shí)例上的其余內(nèi)容則會(huì)被清理。如果目標(biāo)Linode實(shí)例在未來(lái)某個(gè)時(shí)間需要再次進(jìn)行實(shí)時(shí)遷移,則會(huì)重復(fù)執(zhí)行上述步驟。
CPU標(biāo)記
在向來(lái)賓操作系統(tǒng)呈現(xiàn)CPU方面,QEMU有不同的選項(xiàng)。其中一個(gè)選項(xiàng)可將主機(jī)CPU的型號(hào)和功能(即CPU標(biāo)記)直接傳遞給來(lái)賓系統(tǒng)。通過(guò)使用該選項(xiàng),來(lái)賓即可不受約束地使用KVM虛擬化系統(tǒng)所支持的全部能力。當(dāng)Linode首次采用KVM時(shí)(當(dāng)時(shí)還沒(méi)有實(shí)時(shí)遷移功能),為了實(shí)現(xiàn)最大化性能,我們就使用了該選項(xiàng)。然而在開發(fā)實(shí)時(shí)遷移功能的過(guò)程中,該選項(xiàng)為我們?cè)斐闪撕芏嗵魬?zhàn)。
在實(shí)時(shí)遷移的測(cè)試環(huán)境中,源和目標(biāo)主機(jī)是兩臺(tái)完全相同的計(jì)算機(jī)。但在現(xiàn)實(shí)世界中,我們的硬件集群并非100%完全相同的,計(jì)算機(jī)之間的某些配置差異可能能導(dǎo)致產(chǎn)生不同的CPU標(biāo)記。這很重要,因?yàn)楫?dāng)一個(gè)程序被載入Linode的操作系統(tǒng)后,Linode會(huì)向該程序呈現(xiàn)CPU標(biāo)記,為了充分利用這些標(biāo)記,程序可以將軟件中的特定部分載入內(nèi)存。如果一個(gè)Linode實(shí)例被實(shí)時(shí)遷移到不支持該CPU標(biāo)記的目標(biāo)計(jì)算機(jī),程序?qū)?huì)崩潰。這可能導(dǎo)致來(lái)賓操作系統(tǒng)崩潰,甚至導(dǎo)致Linode重啟動(dòng)。
因此在實(shí)現(xiàn)實(shí)時(shí)遷移時(shí),我們必須設(shè)法防止程序因?yàn)镃PU標(biāo)記的不匹配而崩潰。可行的選項(xiàng)有兩個(gè):
- 讓QEMU模擬CPU標(biāo)記。但這可能導(dǎo)致原本快速運(yùn)行的軟件運(yùn)行速度變慢,并且完全無(wú)法調(diào)查原因。
- 收集源計(jì)算機(jī)的CPU標(biāo)記列表,確保目標(biāo)計(jì)算機(jī)具備完全相同的標(biāo)記,隨后再進(jìn)行遷移。這種方式更復(fù)雜,但不會(huì)影響用戶程序的運(yùn)行速度。我們最終選擇了這種方式。
在決定對(duì)源和目標(biāo)的CPU標(biāo)記進(jìn)行匹配后,我們使用下列兩種方法的組合最終實(shí)現(xiàn)了目標(biāo):
- 第一種方法更簡(jiǎn)單。將源硬件的所有CPU標(biāo)記發(fā)送給目標(biāo)硬件,當(dāng)目標(biāo)硬件設(shè)置新的QEMU實(shí)例時(shí),會(huì)通過(guò)檢查來(lái)確保自己至少擁有和源Linode實(shí)例相同的標(biāo)記。如果不匹配,將不進(jìn)行實(shí)時(shí)遷移。
- 第二種方法更復(fù)雜,但可以避免因?yàn)镃PU標(biāo)記不匹配導(dǎo)致的遷移失敗。在發(fā)起實(shí)施遷移前,我們會(huì)對(duì)具備可兼容CPU標(biāo)記的硬件創(chuàng)建一個(gè)列表,隨后從該列表中選擇硬件來(lái)創(chuàng)建目標(biāo)計(jì)算機(jī)。
第二種方法必須能快速執(zhí)行,并且讓我們的工作變得更復(fù)雜。某些情況下,我們需要針對(duì)超過(guò)900臺(tái)計(jì)算機(jī)檢查最多226個(gè)CPU標(biāo)記。為所有這226個(gè)CPU標(biāo)記編寫檢查代碼本就很困難,而這些代碼還需要不斷進(jìn)行維護(hù)。但Linode的創(chuàng)始人Chris Aker提出的一個(gè)驚人想法最終解決了這個(gè)問(wèn)題。方法的關(guān)鍵在于為所有CPU標(biāo)記創(chuàng)建一個(gè)列表,并將其表示為一個(gè)二進(jìn)制字符串。隨后,可以使用Bitwise and("按位與")運(yùn)算來(lái)對(duì)比字符串。
對(duì)于實(shí)時(shí)遷移,CPU標(biāo)記完整列表會(huì)表示為一個(gè)二進(jìn)制字符串,其中每一位都代表一個(gè)標(biāo)記。如果一個(gè)位為"0",代表對(duì)應(yīng)的標(biāo)記不存在; 如果某個(gè)位為"1",則代表標(biāo)記存在。例如,一個(gè)位可以代表AES標(biāo)記,另一個(gè)位可以代表MMX標(biāo)記。這些標(biāo)記己在二進(jìn)制字符串中的位置會(huì)維護(hù)并記錄在案,隨后用于我們數(shù)據(jù)中心內(nèi)的所有計(jì)算機(jī)。
相比維護(hù)一組if語(yǔ)句來(lái)檢查某個(gè)CPU標(biāo)記是否存在,這種列表的維護(hù)工作無(wú)疑更簡(jiǎn)單也更高效。例如,假設(shè)總共需要追蹤并檢查7個(gè)CPU標(biāo)記,這些標(biāo)記可以存儲(chǔ)在一個(gè)8位數(shù)字中(多出的一位供未來(lái)進(jìn)行擴(kuò)展)。例如這樣的字符串可能類似于00111011,最右側(cè)的一位代表AES已啟用,右數(shù)第二位代表MMX已啟用,右數(shù)第三位代表其他標(biāo)記已啟用,以此類推。
實(shí)時(shí)遷移操作會(huì)在源和目標(biāo)計(jì)算機(jī)上針對(duì)CPU標(biāo)記字符串執(zhí)行"按位與"操作。如果兩個(gè)計(jì)算機(jī)的CPU標(biāo)記字符串運(yùn)算結(jié)果相等,意味著目標(biāo)計(jì)算機(jī)是兼容的。我們的內(nèi)部工具可以使用上述算法得到的結(jié)果為可兼容的硬件構(gòu)建一個(gè)列表。該列表會(huì)展示給我們的客戶支持和硬件運(yùn)維團(tuán)隊(duì),這些團(tuán)隊(duì)可以使用我們的內(nèi)部工具來(lái)編排不同的運(yùn)維任務(wù)。
緊跟技術(shù)變化的步伐
隨著時(shí)間推移,Linode會(huì)增加新的功能,我們也許要繼續(xù)努力保證實(shí)時(shí)遷移可以兼容這些功能。引入某些新功能時(shí),可能無(wú)需圍繞實(shí)時(shí)遷移執(zhí)行新的開發(fā)工作,但我們可能依然需要測(cè)試該功能是否可以按照預(yù)期正常工作。對(duì)于某些功能,則可能需要在開發(fā)的早期階段,針對(duì)實(shí)時(shí)遷移進(jìn)行必要的兼容性測(cè)試和相關(guān)工作。
和其他幾乎所有軟件類似,對(duì)于同一件事,通過(guò)不斷研究,總能發(fā)現(xiàn)更好的實(shí)現(xiàn)方法。例如,從長(zhǎng)遠(yuǎn)來(lái)看,為實(shí)時(shí)遷移功能開發(fā)更多模塊化的集成方法,無(wú)疑可以降低維護(hù)負(fù)擔(dān)?;蛘呶覀兩踔量赡軐?shí)時(shí)遷移的相關(guān)功能納入到底層代碼中,從而使其成為L(zhǎng)inode一項(xiàng)拆箱即用的功能。
歡迎點(diǎn)擊這里注冊(cè)Linode免費(fèi)試用賬戶,并通過(guò)強(qiáng)大高效的實(shí)時(shí)遷移功能,體驗(yàn)一下靈活性和可擴(kuò)展性更高的云平臺(tái)是如何幫你保障業(yè)務(wù)連續(xù)性、優(yōu)化資源使用和負(fù)載均衡、改善容災(zāi)和故障恢復(fù)能力。同時(shí),也可以借此機(jī)會(huì)了解Linode云服務(wù)怎樣幫你降低云計(jì)算使用成本,觸達(dá)全球更廣泛的客戶群體。
如您所在的企業(yè)也在考慮采購(gòu)云服務(wù)或進(jìn)行云遷移,
點(diǎn)擊鏈接了解Akamai Linode的解決方案