UCloud元數(shù)據(jù)設計

US3FS通過實現(xiàn)FUSE的接口,將US3中bucket的對象映射為文件,和分布式文件系統(tǒng)不同,沒有mds(metadata server)維護文件元數(shù)據(jù),需要通過HTTP向us3獲取。當文件較多時,大量的請求會瞬間發(fā)出,性能很差。為了解決這一點,US3FS在內(nèi)存中維護了bucket的目錄樹,并設置文件元數(shù)據(jù)的有效時間,避免頻繁和US3交互。

這也帶來了一致性的問題,當多個client修改同一bucket中的文件,其中的緩存一致性無法保證,需要用戶自己取舍。為了提升檢索的性能,文件并沒有像對象存儲以平鋪的方式放在整個目錄中,而是采用了傳統(tǒng)文件系統(tǒng)類似的方式,為每一個目錄構建相關數(shù)據(jù)結構來保存其中的文件,同時inode的設計也盡量簡潔,只保存必要字段,減少內(nèi)存的占用。

目前Inode中保存的字段有uid,gid,size,mtime等,通過US3的元數(shù)據(jù)功能在對象中持久化。例如下圖所示,在US3的bucket中有一個名為”a/b/c/f1″的對象,在文件系統(tǒng)中,會將每一個“/”劃分的前綴映射為目錄,從而實現(xiàn)左邊的目錄樹。

UCloud IO流程設計

對于數(shù)據(jù)的寫入,US3支持大文件的分片上傳。利用這一特性,US3FS通過將數(shù)據(jù)寫入cache,在后臺將數(shù)據(jù)以分片上傳的方式,將數(shù)據(jù)以4MB的chunk寫入到后端存儲中。分片上傳的流程如下圖所示,通過令牌桶限制整個系統(tǒng)的寫入并發(fā)數(shù)。每個分片寫入的線程都會獲取令牌后寫入,通過當文件close時寫入最后一個分片,完成整個上傳流程。

文件的讀取通過在US3FS的cache實現(xiàn)預讀來提升性能。kernel-fuse自身對數(shù)據(jù)的讀寫進行了分片,在不修改內(nèi)核的情況下,IO最大為128K。而大文件的讀取場景一般為連續(xù)的大IO,這種場景下IO會被切成128K的片,不做預讀的話,無法很好的利用網(wǎng)絡帶寬。US3FS的預讀算法如下所示:

如圖所示,第一次同步讀取完成后,會往后進行當前長度的預讀,并將預讀的中點設置為下次觸發(fā)預讀的trigger。之后的讀取如果不連續(xù),則清空之前的狀態(tài),進行新的預讀,如果連續(xù),則判斷當前讀取的結束位置是否不小于觸發(fā)預讀的偏移,如果觸發(fā)預讀,則將預讀窗口的大小擴大為2倍,直到達到設定的閾值。之后以新的窗口進行預讀。如果未觸發(fā),則不進行預讀。預讀對順序讀的性能有很大提升。鑒于US3FS使用場景多為大文件的場景,US3FS本身不對數(shù)據(jù)進行任何緩存。在US3FS之上有內(nèi)核的pagecache,當用戶重復讀取同一文件時pagecache能夠很好的起作用。

UCloud數(shù)據(jù)一致性

由于對象存儲的實現(xiàn)機制原因,當前大文件的寫入,在完成所有的分片上傳之前,數(shù)據(jù)是不可見的,所以對于US3FS的寫入,在close之前,寫入的數(shù)據(jù)都是不可讀的,當close后,US3FS會發(fā)送結束分片的請求,結束整個寫入流程,此時數(shù)據(jù)對用戶可見。

對比測試

在并發(fā)度為64,IO大小為4M測試模型下,40G文件的順序寫和順序讀進行多次測試,平均結果如下:

測試過程中,goofys的內(nèi)存占用比較高,峰值約3.3G,而US3FS比較平穩(wěn),峰值約305M,節(jié)省了90%內(nèi)存空間。s3fs表現(xiàn)相對較好,因為使用本地臨時文件做緩存,所以內(nèi)存占用比較少,但是寫入文件比較大,硬盤空間不足時,性能會下降到表格中的數(shù)據(jù)。

在順序讀的測試中,測試結果可以驗證我們的分析,goofys由于本身設計的原因,在這種場景下性能無法滿足我們的要求。另外在測試移動1G文件的場景中,對比結果如下:

可見在移動需求場景下,特別是大文件居多的場景,通過US3FS能提升上百倍的性能。

總結

總而言之,s3fs和goofys在大文件的讀寫場景下各有優(yōu)劣,相比之下,UCloud優(yōu)刻得US3自研的 US3FS 無論是讀還是寫都有更好的性能,而且和UCloud優(yōu)刻得US3的適配性更強,更易于拓展。

分享到

zhangnn

相關推薦