中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SPDK技術運用對RSSD云硬盤的優化路徑

發布時間:2020-04-21 13:50:16 來源:億速云 閱讀:374 作者:三月 欄目:云計算

下文給大家帶來SPDK技術運用對RSSD云硬盤的優化路徑,希望能夠給大家在實際運用中帶來一定的幫助,云硬盤涉及的東西比較多,理論也不多,網上有很多書籍,今天我們就用億速云在行業內累計的經驗做一個解答。

一 簡介

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

SPDK技術運用對RSSD云硬盤的優化路徑

二 SPDK vhost的基本原理

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

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

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

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

available數組,該數組是一個循環數組,每一項表示一個desc數組的索引,當處理IO請求時,從該數組里拿到一個索引就可以到desc數組里面找到對應的IO請求了。

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

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

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

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

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

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

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

qemu 網盤驅動延時:

SPDK技術運用對RSSD云硬盤的優化路徑

SPDK vhost延時:

SPDK技術運用對RSSD云硬盤的優化路徑

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

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

qemu 網盤驅動延時:

SPDK技術運用對RSSD云硬盤的優化路徑

SPDK vhost延時:

SPDK技術運用對RSSD云硬盤的優化路徑

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

三 SPDK熱升級

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

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

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

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

SPDK技術運用對RSSD云硬盤的優化路徑

四 SPDK在線遷移

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

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

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

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

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

SPDK技術運用對RSSD云硬盤的優化路徑

五 SPDK IO uring體驗

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

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

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

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

2.參考其他bdev的實現,添加針對io uring設備的rpc調用,使得我們可以像創建其他bdev設備那樣創建出io uring的設備;

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

SPDK技術運用對RSSD云硬盤的優化路徑

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

SPDK技術運用對RSSD云硬盤的優化路徑

經過上述修改spdk io uring設備就可以成功創建出來了,我們做下性能的對比:

使用aio bdev的時候:

SPDK技術運用對RSSD云硬盤的優化路徑

使用io uring bdev的時候:

SPDK技術運用對RSSD云硬盤的優化路徑

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

六 總結

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

 看了以上關于SPDK技術運用對RSSD云硬盤的優化路徑,如果大家還有什么地方需要了解的可以在億速云行業資訊里查找自己感興趣的或者找我們的專業技術工程師解答的,億速云技術工程師在行業內擁有十幾年的經驗了。

 

 

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

微博| 龙川县| 宁强县| 佳木斯市| 锡林浩特市| 宁明县| 浮梁县| 巴楚县| 古丈县| 三门县| 石楼县| 南江县| 邢台县| 宁安市| 平舆县| 米易县| 铜川市| 高陵县| 北海市| 台江县| 琼结县| 万州区| 华容县| 南漳县| 蒙阴县| 朝阳市| 万全县| 山阳县| 临邑县| 故城县| 湘阴县| 晋城| 驻马店市| 新巴尔虎右旗| 肥乡县| 凯里市| 盖州市| 岑巩县| 巢湖市| 广东省| 伊宁县|