您好,登錄后才能下訂單哦!
現如今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性能。
早期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加速這樣的產品設計理念、技術細節及未來發展等話題。歡迎點擊下方二維碼或者點擊閱讀原文進行報名,期待您的光臨!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。