SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

10年積累的成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認識你,你也不認識我。但先網(wǎng)站設(shè)計后付款的網(wǎng)站建設(shè)流程,更有普陀免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

下文給大家?guī)鞸PDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑,希望能夠給大家在實際運用中帶來一定的幫助,云硬盤涉及的東西比較多,理論也不多,網(wǎng)上有很多書籍,今天我們就用創(chuàng)新互聯(lián)在行業(yè)內(nèi)累計的經(jīng)驗來做一個解答。

一 簡介

用戶對超高并發(fā)、超大規(guī)模計算等需求推動了存儲硬件技術(shù)的不斷發(fā)展,存儲集群的性能越來越好,延時也越來越低,對整體IO路徑的性能要求也越來越高。在云硬盤場景中,IO請求從生成到后端的存儲集群再到返回之間的IO路徑比較復(fù)雜,虛擬化IO路徑尤其可能成為性能瓶頸,因為虛機內(nèi)所有的IO都需要通過它下發(fā)給后端的存儲系統(tǒng)。我們使用了SPDK來優(yōu)化虛擬化IO路徑,提出了開源未解決的SDPK熱升級和在線遷移方案,并且在高性能云盤場景中成功應(yīng)用,取得了不錯的效果,RSSD云硬盤最高可達120萬IOPS。本文主要分享我們在這方面的一些經(jīng)驗。

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

二 SPDK vhost的基本原理

SPDK(Storage Performance Development Kit )提供了一組用于編寫高性能、可伸縮、用戶態(tài)存儲應(yīng)用程序的工具和庫,基本組成分為用戶態(tài)、輪詢、異步、無鎖 NVMe 驅(qū)動,提供了從用戶空間應(yīng)用程序直接訪問SSD的零拷貝、高度并行的訪問。

在虛擬化IO路徑中,virtio是比較常用的一種半虛擬化解決方案,而virtio底層是通過vring來通信,下面先介紹下virtio vring的基本原理,每個virtio vring 主要包含了以下幾個部分:

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑cdn.xitu.io/2019/5/31/16b0c856d0acf537?w=437&h=307&f=jpeg&s=12871">

desc table數(shù)組,該數(shù)組的大小等于設(shè)備的隊列深度,一般為128。數(shù)組中每一個元素表示一個IO請求,元素中會包含指針指向保存IO數(shù)據(jù)的內(nèi)存地址、IO的長度等基本信息。一般一個IO請求對應(yīng)一個desc數(shù)組元素,當然也有IO涉及到多個內(nèi)存頁的,那么就需要多個desc連成鏈表來使用,未使用的desc元素會通過自身的next指針連接到free_head中,形成一個鏈表,以供后續(xù)使用。

available數(shù)組,該數(shù)組是一個循環(huán)數(shù)組,每一項表示一個desc數(shù)組的索引,當處理IO請求時,從該數(shù)組里拿到一個索引就可以到desc數(shù)組里面找到對應(yīng)的IO請求了。

used 數(shù)組,該數(shù)組與avail類似,只不過用來表示完成的IO請求。當一個IO請求處理完成時,該請求的desc數(shù)組索引就會保存在該數(shù)組中,而前端virtio驅(qū)動得到通知后就會掃描該數(shù)據(jù)判斷是否有請求完成,如果完成就會回收該請求對應(yīng)的desc數(shù)組項以便下個IO請求使用。

SPDK vhost的原理比較簡單,初始化時先由qemu的vhost驅(qū)動將以上virtio vring數(shù)組的信息發(fā)送給SPDK,然后SPDK通過不停的輪尋available數(shù)組來判斷是否有IO請求,有請求就處理,處理完后將索引添加到used數(shù)組中,并通過相應(yīng)的eventfd通知virtio前端。

當SPDK收到一個IO請求時,只是指向該請求的指針,在處理時需要能直接訪問這部分內(nèi)存,而指針指向的地址是qemu地址空間的,顯然不能直接使用,因此這里需要做一些轉(zhuǎn)化。

在使用SPDK時虛機要使用大頁內(nèi)存,虛機在初始化時會將大頁內(nèi)存的信息發(fā)送給SPDK,SPDK會解析該信息并通過mmap映射同樣的大頁內(nèi)存到自己的地址空間,這樣就實現(xiàn)了內(nèi)存的共享,所以當SPDK拿到qemu地址空間的指針時,通過計算偏移就可以很方便的將該指針轉(zhuǎn)換到SPDK的地址空間。

由上述原理我們可以知道SPDK vhost通過共享大頁內(nèi)存的方式使得IO請求可以在兩者之間快速傳遞這個過程中不需要做內(nèi)存拷貝,完全是指針的傳遞,因此極大提升了IO路徑的性能。

我們對比了原先使用的qemu云盤驅(qū)動的延時和使用了SPDK vhost之后的延時,為了單純對比虛擬化IO路徑的性能,我們采用了收到IO后直接返回的方式:

1.單隊列(1 iodepth, 1 numjob)

qemu 網(wǎng)盤驅(qū)動延時:

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

SPDK vhost延時:

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

可見在單隊列情況下延時下降的非常明顯,平均延時由原來的130us下降到了7.3us。

2.多隊列(128 iodepth,1 numjob)

qemu 網(wǎng)盤驅(qū)動延時:

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

SPDK vhost延時:

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

多隊列時IO延時一般會比單隊列更大些,可見在多隊列場景下平均延時也由3341us下降為1090us,下降為原來的三分之一。

三 SPDK熱升級

在我們剛開始使用SPDK時,發(fā)現(xiàn)SPDK缺少一重要功能——熱升級。我們使用SPDK 并基于SPDK開發(fā)自定義的bdev設(shè)備肯定會涉及到版本升級,并且也不能100%保證SPDK進程不會crash掉,因此一旦后端SPDK重啟或者crash,前端qemu里IO就會卡住,即使SPDK重啟后也無法恢復(fù)。

我們仔細研究了SPDK的初始化過程發(fā)現(xiàn),在SPDK vhost啟動初期,qemu會下發(fā)一些配置信息,而SPDK重啟后這些配置信息都丟失了,那么這是否意味著只要SPDK重啟后重新下發(fā)這些配置信息就能使SPDK正常工作呢?我們嘗試在qemu中添加了自動重連的機制,并且一旦自動重連完成,就會按照初始化的順序再次下發(fā)這些配置信息。開發(fā)完成后,初步測試發(fā)現(xiàn)確實能夠自動恢復(fù),但隨著更嚴格的壓測發(fā)現(xiàn)只有在SPDK正常退出時才能恢復(fù),而SPDK crash退出后IO還是會卡住無法恢復(fù)。從現(xiàn)象上看應(yīng)該是部分IO沒有被處理,所以qemu端虛機一直在等待這些IO返回導(dǎo)致的。

通過深入研究virtio vring的機制我們發(fā)現(xiàn)在SPDK正常退出時,會保證所有的IO都已經(jīng)處理完成并返回了才退出,也就是所在的virtio vring中是干凈的。而在意外crash時是不能做這個保證的,意外crash時virtio vring中還有部分IO是沒有被處理的,所以在SPDK恢復(fù)后需要掃描virtio vring將未處理的請求下發(fā)下去。這個問題的復(fù)雜之處在于,virtio vring中的請求是按順序下發(fā)處理的,但實際完成的時候并不是按照下發(fā)的順序的。

假設(shè)在virtio vring的available ring中有6個IO,索引號為1,2,3,4,5,6,SPDK按順序的依次得到這個幾個IO,并同時下發(fā)給設(shè)備處理,但實際可能請求1和4已經(jīng)完成,并返回了成功了,如下圖所示,而2,3,5,6都還沒有完成。這個時候如果crash,重啟后需要將2,3,5,6這個四個IO重新下發(fā)處理,而1和4是不能再次處理的,因為已經(jīng)處理完成返回了,對應(yīng)的內(nèi)存也可能已經(jīng)被釋放。也就是說我們無法通過簡單的掃描available ring來判斷哪些IO需要重新下發(fā),我們需要有一塊內(nèi)存來記錄virtio vring中各個請求的狀態(tài),當重啟后能夠按照該內(nèi)存中記錄的狀態(tài)來決定哪些IO是需要重新下發(fā)處理的,而且這塊內(nèi)存不能因SPDK重啟而丟失,那么顯然使用qemu進程的內(nèi)存是最合適的。所以我們在qemu中針對每個virtio vring申請一塊共享內(nèi)存,在初始化時發(fā)送給SPDK,SPDK在處理IO時會在該內(nèi)存中記錄每個virtio vring請求的狀態(tài),并在意外crash恢復(fù)后能利用該信息找出需要重新下發(fā)的請求。

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

四 SPDK在線遷移

SPDK vhost所提供的虛擬化IO路徑性能非常好,那么我們有沒有可能使用該IO路徑來代替原有的虛擬化IO路徑呢?我們做了一些調(diào)研,SPDK在部分功能上并沒有現(xiàn)有的qemu IO路徑完善,其中尤為重要的是在線遷移功能,該功能的缺失是我們使用SPDK vhost代替原有IO路徑的最大障礙。

SPDK在設(shè)計時更多是為網(wǎng)絡(luò)存儲準備的,所以支持設(shè)備狀態(tài)的遷移,但并不支持設(shè)備上數(shù)據(jù)的在線遷移。而qemu本身是支持在線遷移的,包括設(shè)備狀態(tài)和設(shè)備上的數(shù)據(jù)的在線遷移,但在使用vhost模式時是不支持在線遷移的。主要原因是使用了vhost之后qemu只控制了設(shè)備的控制鏈路,而設(shè)備的數(shù)據(jù)鏈路已經(jīng)托管給了后端的SPDK,也就是說qemu沒有設(shè)備的數(shù)據(jù)流IO路徑所以并不知道一個設(shè)備那些部分被寫入了。

在考察了現(xiàn)有的qemu在線遷移功能后,我們覺著這個技術(shù)難點并不是不能解決的,因此我們決定在qemu里開發(fā)一套針對vhost存儲設(shè)備的在線遷移功能。

塊設(shè)備的在線遷移的原理比較簡單,可以分為兩個步驟,第一個步驟將全盤數(shù)據(jù)從頭到尾拷貝到目標虛機,因為拷貝過程時間較長,肯定會發(fā)生已經(jīng)拷貝的數(shù)據(jù)又被再次寫入的情況,這個步驟中那些再次被寫臟的數(shù)據(jù)塊會在bitmap中被置位,留給第二個步驟來處理,步驟二中通過bitmap來找到那些剩余的臟數(shù)據(jù)塊,將這些臟數(shù)據(jù)塊發(fā)送到目標端,最后會block住所有的IO,然后將剩余的一點臟數(shù)據(jù)塊同步到目標端遷移就完成了。

SPDK的在線遷移原理上于上面是相同的,復(fù)雜之處在于qemu沒有數(shù)據(jù)的流IO路徑,所以我們在qemu中開發(fā)了一套驅(qū)動可以用來實現(xiàn)遷移專用的數(shù)據(jù)流IO路徑,并且通過共享內(nèi)存加進程間互斥的方式在qemu和SPDK之間創(chuàng)建了一塊bitmap用來保存塊設(shè)備的臟頁數(shù)量??紤]到SPDK是獨立的進程可能會出現(xiàn)意外crash的情況,因此我們給使用的pthread mutex加上了PTHREAD_MUTEX_ROBUST特性來防止意外crash后死鎖的情況發(fā)生,整體架構(gòu)如下圖所示:

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

五 SPDK IO uring體驗

IO uring是內(nèi)核中比較新的技術(shù),在上游內(nèi)核5.1以上才合入,該技術(shù)主要是通過用戶態(tài)和內(nèi)核態(tài)共享內(nèi)存的方式來優(yōu)化現(xiàn)有的aio系列系統(tǒng)調(diào)用,使得提交IO不需要每次都進行系統(tǒng)調(diào)用,這樣減少了系統(tǒng)調(diào)用的開銷,從而提供了更高的性能。

SPDK在最新發(fā)布的19.04版本已經(jīng)包含了支持uring的bdev,但該功能只是添加了代碼,并沒有開放出來,當然我們可以通過修改SPDK代碼來體驗該功能。

首先新版本SPDK中只是包含了io uring的代碼甚至默認都沒有開放編譯,我們需要做些修改:

1.安裝最新的liburing庫,同時修改spdk的config文件打開io uring的編譯;

2.參考其他bdev的實現(xiàn),添加針對io uring設(shè)備的rpc調(diào)用,使得我們可以像創(chuàng)建其他bdev設(shè)備那樣創(chuàng)建出io uring的設(shè)備;

3.最新的liburing已經(jīng)將io_uring_get_completion調(diào)用改成了io_uring_peek_cqe,并需要配合io_uring_cqe_seen使用,所以我們也要調(diào)整下SPDK中io uring的代碼實現(xiàn),避免編譯時出現(xiàn)找不到io_uring_get_completion函數(shù)的錯誤:

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

4.使用修改open調(diào)用,使用O_SYNC模式打開文件,確保我們在數(shù)據(jù)寫入返回時就落地了,并且比調(diào)用fdatasync效率更高,我們對aio bdev也做了同樣的修改,同時添加讀寫模式:

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

經(jīng)過上述修改spdk io uring設(shè)備就可以成功創(chuàng)建出來了,我們做下性能的對比:

使用aio bdev的時候:

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

使用io uring bdev的時候:

SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑

可見在最高性能和延時上 io uring都有不錯的優(yōu)勢,IOPS提升了約20%,延遲降低約10%。這個結(jié)果其實受到了底層硬件設(shè)備最大性能的限制,還未達到io uring的上限。

六 總結(jié)

SPDK技術(shù)的應(yīng)用使得虛擬化IO路徑的性能提升不再存在瓶頸,也促使UCloud高性能云盤產(chǎn)品可以更好的發(fā)揮出后端存儲的性能。當然一項技術(shù)的應(yīng)用并沒有那么順利,我們在使用SPDK的過程中也遇到了許多問題,除了上述分享的還有一些bug修復(fù)等我們也都已經(jīng)提交給了SPDK社區(qū),SPDK作為一個快速發(fā)展迭代的項目,每個版本都會給我們帶來驚喜,里面也有很多有意思的功能等待我們發(fā)掘并進一步運用到云盤及其它產(chǎn)品性能的提升上。

 看了以上關(guān)于SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑,如果大家還有什么地方需要了解的可以在創(chuàng)新互聯(lián)行業(yè)資訊里查找自己感興趣的或者找我們的專業(yè)技術(shù)工程師解答的,創(chuàng)新互聯(lián)技術(shù)工程師在行業(yè)內(nèi)擁有十幾年的經(jīng)驗了。

 

 

網(wǎng)站欄目:SPDK技術(shù)運用對RSSD云硬盤的優(yōu)化路徑
網(wǎng)頁鏈接:http://muchs.cn/article32/ihjcsc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航、網(wǎng)站策劃、關(guān)鍵詞優(yōu)化、網(wǎng)站設(shè)計公司微信小程序、商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計