150倍加速機械盤,UCloud雲主機IO加速技術揭祕

現現在CPU的計算能力和磁盤的訪問延遲之間的差距逐漸擴大,使得用戶雲主機的磁盤IO常常成爲嚴重的性能瓶頸,雲計算環境下更加明顯。針對機械盤IO性能低下的問題,咱們經過自研的雲主機IO加速方案,使4K隨機寫的最高性能由原來的300 IOPS提高至4.5W IOPS,提升了150倍,即用機械盤的成本得到了SSD的性能。13年上線至今,該方案已歷經五年的運營實踐,併成功應用於全網93%的標準型雲主機,覆蓋12.7萬臺實例,總容量達26PB。算法

一.爲何須要IO加速網絡

傳統的機械磁盤在尋址時須要移動磁頭到目標位置,移動磁頭的操做是機械磁盤性能低下的主要緣由,雖然各類系統軟件或者IO調度器都致力於減小磁頭的移動來提升性能,但大部分場景下只是改善效果。通常,一塊SATA機械磁盤只有300左右的4K隨機IOPS,對於大多數雲主機來講,300的隨機IOPS哪怕獨享也是不夠的,更況且在雲計算的場景中,一臺物理宿主機上會有多臺雲主機。所以,必需要有其餘的方法來大幅提高IO性能。app

早期SSD價格昂貴,採用SSD必然會帶來用戶使用成本的提高。因而,咱們開始思考可否從技術角度來解決這個問題,經過對磁盤性能特性的分析,咱們開始研發第一代IO加速方案。即便今天SSD愈來愈普及,機械盤憑藉成本低廉以及存儲穩定的特色,仍然普遍應用,而IO加速技術能讓機械盤知足絕大多數應用場景的高IO性能需求。運維

二.IO加速原理及第一代IO加速模塊化

咱們知道機械磁盤的特性是隨機IO性能較差,但順序IO性能較好,如前文中提到的4K隨機IO只能有300 IOPS的性能,但其順序IO性能能夠達到45000 IOPS。性能

IO加速的基本原理就是利用了機械磁盤的這種性能特性,首先系統有兩塊盤:一塊是cache盤,它是容量稍小的機械盤,用來暫時保存寫入的數據;另外一塊是目標盤,它是容量較大的機械盤,存放最終的數據。測試

1. IO的讀寫優化

寫入時將上層的IO順序的寫入到cache盤上,由於是順序的方式寫入因此性能很是好,而後在cache盤空閒時由專門的線程將該盤的數據按照寫入的前後順序回刷到目標盤,使得cache盤保持有必定的空閒空間來存儲新的寫入數據。雲計算

爲了作到上層業務無感知,咱們選擇在宿主機內核態的device mapper層(簡稱dm層)來實現該功能,dm層結構清晰,模塊化較爲方便,實現後對上層體現爲一個dm塊設備,上層不用關心這個塊設備是如何實現的,只須要知道這是一個塊設備能夠直接作文件系統使用。線程

按照上述方式,當新的IO寫入時,dm層模塊會將該IO先寫入cache盤,而後再回刷到目標盤,這裏須要有索引來記錄寫入的IO在cache盤上的位置和在目標盤上的位置信息,後續的回刷線程就能夠利用該索引來肯定IO數據源位置和目標位置。咱們將索引的大小設計爲512字節,由於磁盤的扇區是512字節,因此每次的寫入信息變成了4K數據+512字節索引的模式,爲了性能考慮,索引的信息也會在內存中保留一份。

讀取過程比較簡單,經過內存中的索引判斷須要讀取位置的數據是在cache盤中仍是在目標盤中,而後到對應的位置讀取便可。

寫入的數據通常爲4K大小,這是由內核dm層的特性決定的,當寫入IO大於4K時,dm層默認會將數據切分,好比寫入IO是16K,那麼就會切分紅4個4K的IO;若是寫入數據不是按照4K對齊的,好比只有1024字節,那麼就會先進行特殊處理,首先檢查該IO所覆蓋的數據區,若是所覆蓋的內存區在cache盤中有數據,那麼須要將該數據先寫入目標盤,再將該IO寫入目標盤,這個處理過程相對比較複雜,但在文件系統場景中大部分IO都是4K對齊的,只有極少數IO是非對齊的,因此並不會對業務的性能形成太大影響。

2. 索引的快速恢復與備份

系統在運行過程當中沒法避免意外掉電或者系統關閉等狀況發生,一個健壯的系統必須可以在遇到這些狀況時依然能保證數據的可靠性。當系統啓動恢復時,須要重建內存中的索引數據,這個數據在cache盤中已經和IO數據一塊兒寫入了,但由於索引是間隔存放的,若是每次都從cache盤中讀取索引,那麼,數據的恢復速度會很是慢。

爲此,咱們設計了內存索引的按期dump機制,每隔大約1小時就將內存中的索引數據dump到系統盤上,啓動時首先讀取該dump索引,而後再從cache盤中讀取dump索引以後的最新1小時內的索引,這樣,就大大提高了系統恢復的啓動時間。

依據上述原理,UCloud自研了第一代IO加速方案。採用該方案後,系統在加速隨機寫入方面取得了顯著效果,且已在線上穩定運行。

三.第一代IO加速方案存在的問題

但隨着系統的運行,咱們也發現了一些問題。

1)索引內存佔用較大

磁盤索引由於扇區的緣由最小爲512字節,但內存中的索引其實沒有必要使用這麼多,過大的索引會過分消耗內存。

2)負載高時cache盤中堆積的IO數據較多

IO加速的原理主要是加速隨機IO,對順序IO由於機械盤自己性能較好不須要加速,但該版本中沒有區分順序IO和隨機IO,全部IO都會統一寫入cache盤中,使得cache堆積IO過多。

3)熱升級不友好

初始設計時對在線升級的場景考慮不足,因此第一代IO加速方案的熱升級並不友好。

4)沒法兼容新的512e機械磁盤

傳統機械磁盤物理扇區和邏輯扇區都是512字節,而新的512e磁盤物理扇區是4K了,雖然邏輯扇區還可使用512字節,但性能降低嚴重,因此第一代IO加速方案的4K數據+512字節索引的寫入方式須要進行調整。

5)性能沒法擴展

系統性能取決於cache盤的負載,沒法進行擴展。

四.第二代IO加速技術

上述問題都是在第一代IO加速技術線上運營的過程當中發現的。而且在對新的機械磁盤的兼容性方面,由於傳統的512字節物理扇區和邏輯扇區的512n類型磁盤已經逐漸再也不生產,若是不對系統作改進,系統可能會沒法適應將來需求。所以,咱們在第一代方案的基礎上,着手進行了第二代IO加速技術的研發和優化迭代。

1. 新的索引和索引備份機制

第一代的IO加速技術由於盤的緣由沒法沿用4K+512Byte的格式,爲了解決這個問題,咱們把數據和索引分開,在系統盤上專門建立了一個索引文件,由於系統盤基本處於空閒狀態,因此不用擔憂系統盤負載高影響索引寫入,同時咱們還優化了索引的大小由512B減小到了64B,而數據部分仍是寫入cache盤,以下圖所示:

其中索引文件頭部和數據盤頭部保留兩個4K用於存放頭數據,頭數據中包含了當前cache盤數據的開始和結束的偏移,其後是具體的索引數據,索引與cache盤中的4K數據是一一對應的關係,也就是每一個4K的數據就會有一個索引。

由於索引放在了系統盤,因此也要考慮,若是系統盤發生了不可恢復的損壞時,如何恢復索引的問題。雖然系統盤發生損壞是很是小几率的事件,但一旦發生,索引文件將會徹底丟失,這顯然是沒法接受的。所以,咱們設計了索引的備份機制,每當寫入8個索引,系統就會將這些索引合併成一個4K的索引備份塊寫入cache盤中(具體見上圖中的紫色塊),不滿4K的部分就用0來填充,這樣當系統盤真的發生意外也能夠利用備份索引來恢復數據。

在寫入時會同時寫入索引和數據,爲了提升寫入效率,咱們優化了索引的寫入機制,引入了合併寫入的方式:

當寫入時能夠將須要寫入的多個索引合併到一個4K的write buffer中,一次性寫入該write buffer,這樣避免了每一個索引都會產生一個寫入的低效率行爲,同時也保證了每次的寫入是4K對齊的。

2. 順序IO識別能力

在運營第一代IO加速技術的過程當中,咱們發現用戶在作數據備份、導入等操做時,會產生大量的寫入,這些寫入基本都是順序的,其實不須要加速,但第一代的IO加速技術並無作區分,因此這些IO都會被寫入在cache盤中,致使cache盤堆積的IO過多。爲此,咱們添加了順序IO識別算法,經過算法識別出順序的IO,這些IO不須要經過加速器,會直接寫入目標盤。

一個IO剛開始寫入時是沒法預測此IO是順序的仍是隨機的,通常的處理方式是當一個IO流寫入的位置是連續的,而且持續到了必定的數量時,才能認爲這個IO流是順序的,因此算法的關鍵在於如何判斷一個IO流是連續的,這裏咱們使用了觸發器的方式。

當一個IO流開始寫入時,咱們會在這個IO流寫入位置的下一個block設置一個觸發器,觸發器被觸發就意味着該block被寫入了,那麼就將觸發器日後移動到再下一個block,當觸發器被觸發了必定的次數,咱們就能夠認爲這個IO流是順序的,固然若是觸發器被觸發後必定時間沒有繼續被觸發,那麼咱們就能夠回收該觸發器。

3. 無感知熱升級

第一代的IO加速技術設計上對熱升級支持並不友好,更新存量版本時只能經過熱遷移而後重啓的方式,整個流程較爲繁瑣,因此在開發第二代IO加速技術時,咱們設計了無感知熱升級的方案。

因爲咱們的模塊是位於內核態的dm層,一旦初始化後就會生成一個虛擬的dm塊設備,該塊設備又被上層文件系統引用,因此這個模塊一旦初始化後就不能卸載了。爲了解決這個問題,咱們設計了父子模塊的方式,父模塊在子模塊和dm層之間起到一個橋樑的做用,該父模塊只有很是簡單的IO轉發功能,並不包含複雜的邏輯,所以能夠確保父模塊不須要進行升級,而子模塊包含了複雜的業務邏輯,子模塊能夠從父模塊中卸載來實現無感知熱升級:

上圖中的binlogdev.ko就是父模塊,cachedev.ko爲子模塊,當須要熱升級時能夠將cache盤設置爲只讀模式,這樣cache盤只回刷數據再也不寫入,等cache盤迴刷完成後,能夠認爲後續的寫入IO可直接寫入目標盤而不用擔憂覆蓋cache盤中的數據,這樣子模塊就能夠順利拔出替換了。

這樣的熱升級機制不只實現了熱升級的功能,還提供了故障時的規避機制,在IO加速技術的灰度過程當中,咱們就發現有個偶現的bug會致使宿主機重啓,咱們第一時間將全部cache盤設置爲只讀,以免故障的再次發生,並爭取到了debug的時間。

4. 兼容512e機械磁盤

新一代的機械磁盤以512e爲主,該類型的磁盤須要寫入IO按照4K對齊的方式才能發揮最大性能,因此原先的4K+512B的索引格式已經沒法使用,咱們也考慮過把512B的索引擴大到4K,但這樣會致使索引佔用空間過多,且寫入時也會額外佔用磁盤的帶寬效率過低,因此最終經過將索引放到系統盤並結合上文提到的合併寫入技術來解決該問題。

5. 性能擴展和提高

在第一代的IO加速技術中只能使用1塊cache盤,當這塊cache盤負載較高時就會影響系統的性能,在第二代IO加速中,咱們設計了支持多塊cache盤,並按照系統負載按需插入的方式,使加速隨機IO的能力隨着盤數量的提高而提高。在本地cache盤以及網絡cache盤都採用SATA機械磁盤的條件下,測試發現,隨着使用的cache盤數量的增多,隨機寫的性能也獲得了大幅度的提高。

在只使用一塊本地cache盤時,隨機寫性能可達4.7W IOPS:

在使用一塊本地cache盤加一塊網絡cache盤時,隨機寫性能可達9W IOPS:

在使用一塊本地cache盤加兩塊網絡cache盤時,隨機寫性能可達13.6W IOPS:

目前,咱們已經大規模部署應用了第二代IO加速技術的雲主機。得益於上述設計,以前備受困擾的cache盤IO堆積過多、性能瓶頸等問題獲得了極大的緩解,特別是IO堆積的問題,在第一代方案下,負載較高時常常觸發並致使性能損失和運維開銷,採用第二代IO加速技術後,該監控告警只有偶現的幾例觸發。

五.寫在最後

雲主機IO加速技術極大提高了機械盤隨機寫的處理能力,使得用戶能夠利用較低的價格知足業務需求。且該技術的本質並不僅僅在於對機械盤加速,更是使系統層面具有了一種能夠把性能和所處的存儲介質進行分離的能力,使得IO的性能並不受限於其所存儲的介質。此外,一項底層技術在實際生產環境中的大規模應用,其設計很是關鍵,特別是版本熱升級、容錯以及性能考慮等都須要仔細斟酌。但願本文能夠幫助你們更好的理解底層技術的特色及應用,並在之後的設計中作出更好的改進。

— END —

即將於12/21舉辦的「UCloud用戶大會暨TIC上海站」上,UCloud將和參會者一塊兒探討諸如雲主機IO加速這樣的產品設計理念、技術細節及將來發展等話題。歡迎點擊下方二維碼或者點擊閱讀原文進行報名,期待您的光臨!

相關文章
相關標籤/搜索