在數(shù)字化業(yè)務(wù)實(shí)踐中,某些客有些用戶的業(yè)務(wù)場(chǎng)景需要在短時(shí)間內(nèi)能夠批量創(chuàng)建大量的云主機(jī),這些典型業(yè)務(wù)場(chǎng)景包括:
1.芯片設(shè)計(jì),由于單機(jī)無(wú)法滿足高計(jì)算需求,需要上百臺(tái)云主機(jī)完成眾多job的計(jì)算;
2.3D渲染,基礎(chǔ)鏡像大且需要大量云主機(jī)滿足不同渲染需求;
3.搶購(gòu)類業(yè)務(wù),需要大量云主機(jī)并發(fā)以提高搶購(gòu)效率。創(chuàng)建云主機(jī)的速度關(guān)系到這些客戶的核心體驗(yàn)。
在創(chuàng)建云主機(jī)過(guò)程中,最耗時(shí)的操作為克隆虛擬機(jī)鏡像這一步驟,需要將虛擬機(jī)鏡像從鏡像源復(fù)制一份到云盤(pán)集群。虛擬機(jī)鏡像包含虛擬機(jī)上的操作系統(tǒng)及用戶預(yù)裝的軟件,一個(gè)完整的鏡像數(shù)據(jù)量非常大,從幾GB到幾十GB不等,在實(shí)踐中,甚至有的鏡像數(shù)據(jù)達(dá)到幾百GB。創(chuàng)建N臺(tái)云主機(jī)意味著將鏡像數(shù)據(jù)復(fù)制分發(fā)N份,而且大部分公有云存儲(chǔ)都采用三副本技術(shù)進(jìn)行數(shù)據(jù)冗余,這意味著復(fù)制分發(fā)的數(shù)據(jù)量還要放大三倍。因此,在大批量創(chuàng)建云主機(jī)場(chǎng)景下,復(fù)制分發(fā)海量數(shù)據(jù)需要用戶等待大量時(shí)間,這個(gè)時(shí)間往往是用戶業(yè)務(wù)無(wú)法接受的。
為了緩解用戶批量創(chuàng)建云盤(pán)主機(jī)耗時(shí)過(guò)長(zhǎng)的問(wèn)題,我們采用過(guò)鏡像預(yù)灌作為過(guò)渡方案,即提前為用戶克隆好系統(tǒng)盤(pán)鏡像。該方案存在明顯缺陷,不僅需要提前知曉客戶的熱門(mén)鏡像,超額預(yù)灌也會(huì)額外占用后端存儲(chǔ)資源。為了從根本上解決批量創(chuàng)建云盤(pán)主機(jī)耗時(shí)過(guò)長(zhǎng)問(wèn)題,我們?cè)O(shè)計(jì)了基于ROW(Redirect-On-Write)的克隆/快照技術(shù),實(shí)現(xiàn)了寫(xiě)時(shí)重定向的鏈?zhǔn)娇寺。_(dá)到了秒級(jí)克隆的效果。
一、快照克隆技術(shù)選型
COW(Copy-On-Write),也被稱之寫(xiě)時(shí)復(fù)制快照技術(shù),這種方式通常也被稱為“元數(shù)據(jù)(源數(shù)據(jù)指針表)”拷貝。顧名思義,如果試圖改寫(xiě)源數(shù)據(jù)塊上的原始數(shù)據(jù),首先要將原始數(shù)據(jù)拷貝到新數(shù)據(jù)塊中,然后再進(jìn)行改寫(xiě)。當(dāng)還原快照需要引用原始數(shù)據(jù)時(shí),快照軟件會(huì)將原始數(shù)據(jù)原有的指針映射到新數(shù)據(jù)塊上。
ROW(Redirect-On-Write),也被稱之為寫(xiě)時(shí)重定向。ROW的實(shí)現(xiàn)原理與COW非常相似,區(qū)別在于ROW對(duì)原始數(shù)據(jù)卷的首次寫(xiě)操作,會(huì)將新數(shù)據(jù)重定向到預(yù)留的快照卷中,而非COW一般會(huì)使用新數(shù)據(jù)將原始數(shù)據(jù)覆蓋。所以,ROW快照中的原始數(shù)據(jù)依舊保留在源數(shù)據(jù)卷中,并且為了保證快照數(shù)據(jù)的完整性,在創(chuàng)建快照時(shí),源數(shù)據(jù)卷狀態(tài)會(huì)由讀寫(xiě)變成只讀的。如果對(duì)一個(gè)虛擬機(jī)做了多次快照,就產(chǎn)生了一個(gè)快照鏈,虛擬機(jī)的磁盤(pán)卷始終掛載在快照鏈的最末端,即虛擬機(jī)的寫(xiě)操作全都會(huì)落盤(pán)到最末端的快照卷中。
該特征導(dǎo)致了一個(gè)問(wèn)題,就是如果一共做了10次快照,那么在恢復(fù)到最新的快照點(diǎn)時(shí),則需要通過(guò)合并10個(gè)快照卷來(lái)得到一個(gè)完整的最新快照點(diǎn)數(shù)據(jù);如果是恢復(fù)到第8次快照時(shí)間點(diǎn),那么就需要將前8次的快照卷合并成為一個(gè)完整的快照點(diǎn)數(shù)據(jù)。從這里可以看出ROW的主要缺點(diǎn)是沒(méi)有一個(gè)完整的快照卷,其快照之間的關(guān)系是鏈?zhǔn)降模绻煺諏蛹?jí)越多,進(jìn)行快照恢復(fù)時(shí)的系統(tǒng)開(kāi)銷會(huì)比較大。但ROW的優(yōu)勢(shì)在于其解決了COW快照寫(xiě)兩次的問(wèn)題,所以就寫(xiě)性能而言,ROW無(wú)疑是優(yōu)于COW的。
可以看出,ROW與COW最大的不同就是:COW的快照卷存放的是原始數(shù)據(jù),而ROW的快照卷存放的是新數(shù)據(jù)。因?yàn)镽OW這種設(shè)定,所以其多個(gè)快照之間的關(guān)系必定是鏈?zhǔn)降模驗(yàn)樽钚乱淮慰煺盏脑紨?shù)據(jù)很可能就存放在了上一次快照時(shí)創(chuàng)建的快照卷中。另外,對(duì)于分布式系統(tǒng)來(lái)說(shuō),由于數(shù)據(jù)分散分布在不同存儲(chǔ)節(jié)點(diǎn)上,進(jìn)而提供了并發(fā)讀的機(jī)會(huì),因此,在分布式存儲(chǔ)系統(tǒng)中,ROW的讀寫(xiě)性能優(yōu)于COW。
鑒于ROW與COW的對(duì)比優(yōu)勢(shì),以及UDisk自身分布式部署特點(diǎn),我們最終采用基于ROW的方式實(shí)現(xiàn)內(nèi)部快照,并對(duì)UDisk的整體架構(gòu)進(jìn)行改進(jìn)優(yōu)化。為了降低批量創(chuàng)建云盤(pán)主機(jī)時(shí)對(duì)鏡像存儲(chǔ)集群的壓力,引入Frigga模塊,管理UDisk內(nèi)部鏡像,期望相同鏡像只從鏡像存儲(chǔ)集群拷貝一次,UDisk集群內(nèi)部共享。
二、方案整體架構(gòu)設(shè)計(jì)
Access:UDisk接入服務(wù),接收外部請(qǐng)求,并下發(fā)請(qǐng)求到相應(yīng)存儲(chǔ)集群中
Frigga:鏡像分發(fā)管理模塊,管理從鏡像系統(tǒng)克隆的鏡像。全局部署,采用主備模式,對(duì)于鏡像集群中存儲(chǔ)鏡像的云盤(pán)提供新建、查詢等功能;
Metaserver:UDisk存儲(chǔ)集群元數(shù)據(jù)管理模塊,存儲(chǔ)管理集群快照克隆的鏈?zhǔn)疥P(guān)系和集群的路由信息;
Chunk:UDisk存儲(chǔ)集群后端數(shù)據(jù)存儲(chǔ)引擎,負(fù)責(zé)數(shù)據(jù)的實(shí)際讀寫(xiě)
Client:客戶端服務(wù),UDisk存儲(chǔ)接入模塊,部署在宿主機(jī)上,負(fù)責(zé)虛機(jī)io下發(fā)到后端存儲(chǔ)集群
Ymer:負(fù)責(zé)從鏡像系統(tǒng)拷貝鏡像到UDisk存儲(chǔ)集群
鏡像集群:特殊的UDisk存儲(chǔ)集群,作為鏡像系統(tǒng)Cache,后端部署與普通集群一致。該集群只存儲(chǔ)基礎(chǔ)鏡像數(shù)據(jù)和克隆云盤(pán)數(shù)據(jù),客戶批量創(chuàng)建云盤(pán)主機(jī)創(chuàng)建的云盤(pán)系統(tǒng)盤(pán)都會(huì)落在該集群中,后期通過(guò)遷移系統(tǒng)在線將云盤(pán)系統(tǒng)盤(pán)打散遷移到UDisk存儲(chǔ)集群中,遷移過(guò)程用戶無(wú)感知。該集群作為基礎(chǔ)鏡像緩存池,由Frigga模塊采用LRU策略淘汰冷鏡像數(shù)據(jù),只存儲(chǔ)用戶的高頻熱點(diǎn)鏡像。
系統(tǒng)盤(pán)克隆整體流程
云主機(jī)服務(wù)下發(fā)系統(tǒng)盤(pán)克隆請(qǐng)求到Access接入服務(wù),Access根據(jù)請(qǐng)求中的鏡像ID向Frigga查詢當(dāng)前鏡像是否已存在后端鏡像集群。
若存在,則響應(yīng)Access鏡像存在,同時(shí)返回鏡像對(duì)應(yīng)云盤(pán)ID,Access根據(jù)云盤(pán)ID重新組織克隆請(qǐng)求,下發(fā)到鏡像集群Metaserver服務(wù),Metaserver接收請(qǐng)求執(zhí)行內(nèi)部克隆,更新克隆盤(pán)與鏡像盤(pán)對(duì)應(yīng)關(guān)系,并將關(guān)系信息同步給集群內(nèi)所有Chunk服務(wù),通知完成后向上層返回,克隆流程結(jié)束(上圖綠色線+黑色線部分)。整個(gè)過(guò)程不涉及與鏡像系統(tǒng)的交互,無(wú)數(shù)據(jù)拷貝,純內(nèi)存操作,毫秒級(jí)時(shí)間內(nèi)完成。
當(dāng)請(qǐng)求的鏡像不存在時(shí),F(xiàn)rigga本地內(nèi)存新增鏡像記錄,并持久化DB。然后響應(yīng)Access鏡像不存在,需要從鏡像系統(tǒng)克隆鏡像。Access接收響應(yīng)后,向Metaserver下發(fā)從鏡像系統(tǒng)克隆請(qǐng)求,Metaserver創(chuàng)建鏡像云盤(pán)并通知Ymer從鏡像系統(tǒng)拷貝鏡像數(shù)據(jù),通知成功后,向上層Access返回已開(kāi)始克隆,Access接收到響應(yīng)后再次向Metaserver下發(fā)從鏡像云盤(pán)的內(nèi)部克隆請(qǐng)求,流程同上(上圖紅色線+黑色線部分)。不過(guò)此時(shí)鏡像尚未克隆完成,F(xiàn)rigga會(huì)不斷查詢鏡像云盤(pán)狀態(tài),直到數(shù)據(jù)拷貝完成,此時(shí)系統(tǒng)盤(pán)可用。相較上面流程,多了一次從鏡像系統(tǒng)拷貝數(shù)據(jù)的過(guò)程,但也只需要一次拷貝,降低了對(duì)鏡像系統(tǒng)的負(fù)載壓力。
UDisk整體架構(gòu)如何適配是核心問(wèn)題,幾乎涉及到UDisk所有模塊的改動(dòng),下文將詳細(xì)介紹如何基于ROW實(shí)現(xiàn)內(nèi)部快照/克隆的技術(shù)細(xì)節(jié)。
三、快照/克隆云盤(pán)實(shí)現(xiàn)原理
為了便于理解,先介紹幾個(gè)基本概念:1.UDisk提供塊存儲(chǔ)服務(wù),對(duì)外可見(jiàn)的為一個(gè)個(gè)裸設(shè)備(云盤(pán),也稱為邏輯盤(pán),lc),每塊云盤(pán)對(duì)應(yīng)一個(gè)全局唯一標(biāo)識(shí)extern_id,每個(gè)extern_id會(huì)被分配到后端某個(gè)存儲(chǔ)集群,且在后端集群中為extern_id分配唯一id,即lc_id;2.每個(gè)Chunk服務(wù)管理一塊物理磁盤(pán),底層以PC(4MB)為粒度管理整個(gè)物理磁盤(pán)的容量,并提供IO讀寫(xiě)服務(wù)。
extern_id:云盤(pán)資源id,全局唯一
lc:邏輯盤(pán),即云盤(pán)
lc_id:云盤(pán)在后端存儲(chǔ)集群內(nèi)id,存儲(chǔ)集群內(nèi)唯一
PC:邏輯存儲(chǔ)單元
Frigga鏡像管理
Frigga設(shè)計(jì)為主備模式,提高系統(tǒng)可用性。Frigga負(fù)責(zé)鏡像的導(dǎo)入,后端存儲(chǔ)集群鏡像管理以及克隆調(diào)度。與Ymer配合實(shí)現(xiàn)UDisk存儲(chǔ)集群間鏡像共享,從鏡像系統(tǒng)拷貝一次鏡像,UDisk存儲(chǔ)集群內(nèi)數(shù)據(jù)共享,大大減輕鏡像系統(tǒng)負(fù)載。Frigga根據(jù)LRU策略管理本地鏡像,防止無(wú)效鏡像/冷鏡像占用存儲(chǔ)資源,當(dāng)鏡像集群使用容量達(dá)到設(shè)定閾值時(shí),根據(jù)LRU策略淘汰冷鏡像。
當(dāng)鏡像集群容量到達(dá)使用閾值后,會(huì)根據(jù)LRU策略主動(dòng)刪除長(zhǎng)時(shí)間未使用鏡像。為防止單鏡像集群內(nèi)從單一鏡像克隆過(guò)多云盤(pán)引起的訪問(wèn)熱點(diǎn)問(wèn)題,F(xiàn)rigga為每個(gè)鏡像集群內(nèi)的鏡像設(shè)置單鏡像最大支持克隆盤(pán)數(shù)量閾值,當(dāng)克隆盤(pán)數(shù)量超過(guò)設(shè)定閾值后,會(huì)重新從鏡像系統(tǒng)重新拷貝鏡像。
Metaserver元數(shù)據(jù)以及路由管理
UDisk原有架構(gòu)設(shè)計(jì)中邏輯盤(pán)之間相互獨(dú)立,無(wú)相互關(guān)聯(lián)。為了實(shí)現(xiàn)UDisk存儲(chǔ)集群內(nèi)部鏡像共享(鏡像在鏡像集群中也以邏輯盤(pán)存在),以邏輯盤(pán)lc粒度管理鏡像/快照/克隆盤(pán)關(guān)系,通過(guò)維護(hù)邏輯盤(pán)之間的關(guān)系實(shí)現(xiàn)快照的創(chuàng)建/克隆等操作,邏輯盤(pán)間的對(duì)應(yīng)關(guān)系由Metaserver統(tǒng)一管理,并同步給Chunk以及Client服務(wù)。對(duì)盤(pán)多次打快照后,從不同快照克隆云盤(pán)后,Metaserver側(cè)維護(hù)的邏輯盤(pán)之間的拓?fù)浣Y(jié)構(gòu)如下圖所示:
從同一鏡像批量克隆出多塊克隆盤(pán)后,邏輯盤(pán)之間的拓?fù)浣Y(jié)構(gòu)如下,所有克隆盤(pán)均指向鏡像云盤(pán),只需要鏡像盤(pán)從鏡像系統(tǒng)拷貝一次,其他克隆盤(pán)的創(chuàng)建均為內(nèi)存操作,Metaserver只需維護(hù)克隆盤(pán)到鏡像之間的映射關(guān)系即可,這樣極大提高了系統(tǒng)盤(pán)的克隆速度。
邏輯盤(pán)間的關(guān)系在Metaserver內(nèi)存中都是一條條的鏈,鏈上的各邏輯盤(pán)都依賴其上層節(jié)點(diǎn),從鏈的末尾節(jié)點(diǎn)可依次向上層查詢直到根節(jié)點(diǎn)。Metaserver會(huì)將邏輯盤(pán)之間的映射關(guān)系信息實(shí)時(shí)同步給Client以及Chunk服務(wù),Client和Chunk服務(wù)與Metaserver之間也保持心跳消息,通過(guò)心跳主動(dòng)同步邏輯盤(pán)映射關(guān)系信息,防止網(wǎng)絡(luò)分區(qū)導(dǎo)致的信息不一致。Metaserver通過(guò)version機(jī)制管理映射關(guān)系變化,通過(guò)比對(duì)Metaserver與Client/Chunk的version確定是否需要同步最新映射關(guān)系。
按照UDisk分布式設(shè)計(jì)原則,鏡像數(shù)據(jù)被分散存儲(chǔ)在鏡像集群不同物理主機(jī)上,按原有路由策略,克隆盤(pán)讀取鏡像數(shù)據(jù)時(shí),可能會(huì)存在跨機(jī)器訪問(wèn)的問(wèn)題,增加數(shù)據(jù)讀取時(shí)延,影響云主機(jī)啟動(dòng)速度。為此,我們優(yōu)化了路由策略:克隆盤(pán)和鏡像擁有相同的路由信息,克隆盤(pán)和鏡像數(shù)據(jù)由相同的Chunk服務(wù)管理。這樣,當(dāng)云主機(jī)啟動(dòng)加載系統(tǒng)盤(pán)數(shù)據(jù)時(shí),可以直接讀取對(duì)應(yīng)Chunk上的鏡像數(shù)據(jù),本地讀操作,減少網(wǎng)絡(luò)訪問(wèn)時(shí)延。
Client IO下發(fā)
Client作為UDisk存儲(chǔ)集群的接入服務(wù),負(fù)責(zé)將虛機(jī)的IO下發(fā)到存儲(chǔ)集群不同的Chunk服務(wù)上,為了保證將克隆盤(pán)的IO下發(fā)到對(duì)應(yīng)鏡像所在Chunk服務(wù)上,Client側(cè)需要獲取對(duì)應(yīng)克隆盤(pán)的所有映射關(guān)系,從而獲取到鏡像信息,以鏡像的路由策略下發(fā)IO。
Chunk側(cè)IO讀/寫(xiě)流程優(yōu)化
Chunk以PC為粒度管理磁盤(pán),并處理IO,只有寫(xiě)IO時(shí)Chunk才可能分配新PC。Chunk除了從Metaserver同步邏輯盤(pán)之間的映射關(guān)系外,還維護(hù)自身管理的PC信息。對(duì)lc多次做快照后,Chunk維護(hù)的PC間拓?fù)浣Y(jié)構(gòu)如下圖:
從同一鏡像克隆出多塊盤(pán)后,Chunk維護(hù)的PC間拓?fù)浣Y(jié)構(gòu)如下:
Chunk接收Client IO按照PC讀寫(xiě)磁盤(pán),每個(gè)PC對(duì)應(yīng)一個(gè)pcmeta元數(shù)據(jù),該元數(shù)據(jù)記錄了PC云盤(pán)與物理盤(pán)的映射關(guān)系,其中重定向標(biāo)記位(bitmap)表示該數(shù)據(jù)是否需要從父節(jié)點(diǎn)讀取數(shù)據(jù);每個(gè)標(biāo)記位代表256k數(shù)據(jù)重定向結(jié)果,對(duì)于新建的克隆盤(pán)PC初始化時(shí)所有的bitmap都是1,表示每個(gè)256k都需要重定向讀寫(xiě)。Client下發(fā)的IO可以由一個(gè)四元組PC Entry(lc_id, pc_no, offset, length)表示,代表要讀寫(xiě)的邏輯盤(pán)、讀寫(xiě)位置所屬PC、PC內(nèi)位置、讀寫(xiě)大小以及數(shù)據(jù)。
讀io重定向
對(duì)于讀請(qǐng)求,首先根據(jù)四元組PC Entry確認(rèn)PC是否存在,若存在,再根據(jù)pcmeta中bitmap對(duì)應(yīng)位是否為1確認(rèn)是否需要重定向讀,bitmap為0說(shuō)明讀取的數(shù)據(jù)在當(dāng)前PC上,直接讀取數(shù)據(jù)即可。發(fā)現(xiàn)對(duì)應(yīng)的bitmap為1就尋找父節(jié)點(diǎn)繼續(xù)判斷標(biāo)記位,直到父節(jié)點(diǎn)的標(biāo)記位為0表示不需要重定向直接讀取父節(jié)點(diǎn)PC對(duì)應(yīng)位置的數(shù)據(jù)。
寫(xiě)io重定向
對(duì)于寫(xiě)io判斷首先判斷PC是否存在,如果克隆的PC存在,再判斷bitmap是否為1(需要重定向),如果為1就會(huì)找父節(jié)點(diǎn)對(duì)應(yīng)的PC,先將父節(jié)點(diǎn)對(duì)應(yīng)PC的256k數(shù)據(jù)讀取出來(lái),再與當(dāng)前寫(xiě)io數(shù)據(jù)做合并,再寫(xiě)入對(duì)應(yīng)的磁盤(pán)。如果克隆的PC不存在,則先創(chuàng)建PC,創(chuàng)建PC的pcmeta中bitmap設(shè)置為1,再按照之前PC存在的流程同樣處理io。
四、總結(jié)
為了能夠達(dá)到秒級(jí)克隆的效果,達(dá)到短時(shí)間創(chuàng)建大批量虛機(jī)的需求,我們采用了ROW的方法,同時(shí)利用了鏡像緩存池作為熱點(diǎn)鏡像數(shù)據(jù),提高了基礎(chǔ)鏡像克隆與內(nèi)部克隆的速度與效率,能夠達(dá)到5min內(nèi)批量創(chuàng)建1000以上虛機(jī)的要求。
目前,該方案已在海外洛杉磯、新加坡機(jī)房全量開(kāi)放,國(guó)內(nèi)上海、廣州、北京、香港等機(jī)房已針對(duì)特定客戶開(kāi)放。主要目標(biāo)客戶為短時(shí)間內(nèi)有批量創(chuàng)建虛機(jī)需求或者大容量基礎(chǔ)鏡像的客戶,可以大大縮短用戶創(chuàng)建虛機(jī)時(shí)間。目前,可支撐用戶業(yè)務(wù)高峰期批量2500臺(tái)虛機(jī)的創(chuàng)建需求。