面向高性能計算場景的存儲系統(tǒng)解決方案
我們進(jìn)入這次分享的主題,將圍繞四個部分展開。
第一部分介紹一下高性能計算場景下面臨哪些存儲問題,第二部分簡要介紹一下百度內(nèi)部的高性能存儲實踐經(jīng)驗,第三部分介紹百度滄海是如何解答這些存儲問題的,最后是一個客戶案例。
1. 高性能場景下的存儲問題
1.1. 什么是高性能計算
高性能計算是 High Performance Computing 的縮寫,簡稱 HPC。這并不是這些年來才出現(xiàn)的一個詞,已經(jīng)有很長時間的歷史了,假如我們?nèi)ゲ殚喚S基百科的話,會發(fā)現(xiàn)在維基百科實際上把 HPC 當(dāng)做超級計算機(jī)的一個同義詞匯,而超級計算機(jī)是這樣定義的:就是那些性能上比同時代的個人計算機(jī)快到至少一到兩級的計算機(jī),可以叫做超級計算機(jī)。
提到超級計算機(jī)這個詞的時候,大家一定不要把它想象成一臺巨大的機(jī)器,實際上一個超級計算機(jī)通常是一整個集群的機(jī)器,分布在一個數(shù)據(jù)中心內(nèi)部。國內(nèi)目前最強(qiáng)大的超級計算機(jī)是太湖之光,在高性能計算 TOP 500 榜單上處于第四的位置。它最大的一個特點就是所使用的 CPU 都是國產(chǎn)的。HPC 領(lǐng)域近年來呈現(xiàn)出一些新的發(fā)展趨勢:
- 趨勢一:高性能計算場景越來越豐富了。HPC 在原來的使用上主要是局限在一些科學(xué)計算、工業(yè)仿真這樣的一些傳統(tǒng)場景,現(xiàn)在越來越多的行業(yè)發(fā)現(xiàn),高性能計算能夠解決他們的實際問題,開始采納高性能計算的方法和方案。
- 趨勢二:高性能計算上云越來越流行。隨著云計算的發(fā)展,云廠商提供的網(wǎng)絡(luò)、存儲、計算的硬件設(shè)施性能越來越好,一些原來因硬件性能問題沒有辦法上云的高性能計算具備了上云的條件,云原生或者混合云的計算模式變得越來越流行。云上進(jìn)行高性能計算的最大優(yōu)勢就是彈性。傳統(tǒng)超級計算機(jī)在建設(shè)的時候需要提前規(guī)劃資源需求,建設(shè)龐大的數(shù)據(jù)中心,前期利用率不高資源浪費(fèi)大,后期擴(kuò)建成本高昂,普通客戶也很難享受到高性能計算的紅利。但云的彈性可以讓用戶很容易運(yùn)行高性能計算程序,有計算需求時隨時按需創(chuàng)建資源,計算完銷毀資源。在這種模式下,用戶實際上只需要為當(dāng)時正在使用的資源付費(fèi),因此可以節(jié)省很多成本。
- 趨勢三:跨界合作變得越來越普遍。近些年來業(yè)界觀察到,大數(shù)據(jù)和 AI 實際上也是兩種以計算為主的場景。和 HPC 相比,在方法上可以互相借鑒、互通有無。這些種類的計算之間的邊界正變得越來越模糊。一方面 AI 和大數(shù)據(jù)領(lǐng)域在積極地吸納傳統(tǒng) HPC 里面的一些方法,另外一方面?zhèn)鹘y(tǒng)的 HPC 也開始意識到,GPU 這樣的專用硬件在特定運(yùn)算方面會比 CPU 快很多,所以從業(yè)人員也在有意識地引入 GPU 的硬件和一些新的計算方法。
在這些發(fā)展趨勢的推動下,如今我們談?wù)摳咝阅苡嬎愕臅r候,通常是指三類計算:
- 第一類是傳統(tǒng)意義上的超級計算機(jī),通常就叫 HPC。氣象預(yù)報、石油勘探、碰撞仿真是典型的 HPC 應(yīng)用。
- 第二類是人工智能領(lǐng)域的計算,叫 AI HPC,或者直接簡稱 AI。這一類計算有一個特點是會大量的使用 GPU 算力,主要的場景包括大規(guī)模的深度學(xué)習(xí)訓(xùn)練等。
- 第三類是跟大數(shù)據(jù)結(jié)合的一類高性能計算,叫高性能數(shù)據(jù)分析HPDA。最近一些年,大家可能會關(guān)注了一個新聞,很多國家的科學(xué)家一起成立了一個人類基因組計劃,對人類的基因組進(jìn)行測序?;驕y序就是一個很典型的 HPDA 場景。
國外的一些市場調(diào)研的機(jī)構(gòu)對這三類場景的市場份額進(jìn)行了調(diào)研。從調(diào)研的數(shù)據(jù),我們可以發(fā)現(xiàn),傳統(tǒng) HPC 在高性能計算領(lǐng)域仍然占據(jù)了主導(dǎo)地位,但是 AI HPC 和 HPDA 占據(jù)的市場份額其實在逐年擴(kuò)大。以上就是三種典型的高性能計算,接下來我來跟大家分享一下,在這些場景里面到底面臨哪些存儲問題。
1.2. 傳統(tǒng) HPC 中的存儲問題
傳統(tǒng)HPC有很多科學(xué)計算問題,例如方程式的求解,這里很重要的一個基礎(chǔ)問題就是矩陣運(yùn)算。當(dāng)一個矩陣非常大的時候,需要將矩陣拆解成很多子矩陣,由多個節(jié)點來協(xié)作完成計算。下面舉一個簡單的例子來描述一下這個過程。
四個進(jìn)程 P1,P2,P3,P4,一起計算一個很大的矩陣,每一個進(jìn)程分到了矩陣的一個子矩陣,負(fù)責(zé)子矩陣的運(yùn)算。這一整個矩陣在存儲系統(tǒng)里面是用一個大文件來表示的。這實際上是一個很自然的表示,如果我們對 C 語言或者其它的編程語言有一定了解,就會知道,編程語言在內(nèi)存中去模擬多維數(shù)組或矩陣的時候,會使用一個連續(xù)的內(nèi)存空間,通過下標(biāo)計算出在連續(xù)內(nèi)存空間中的偏移(offset),從而得到元素的實際存儲位置。這是一個很直觀的表達(dá)方法,在 HPC 計算里面,也采用類似的表達(dá)方式,只是數(shù)據(jù)不是在內(nèi)存里,而是在存儲系統(tǒng)的文件上。這樣的一種表示方式雖然邏輯上簡單,但帶來了兩個問題需要解決。
- 第一個問題是 I/O 效率問題。每一個進(jìn)程負(fù)責(zé)的數(shù)據(jù),實際上會散落到矩陣文件不連續(xù)的位置上面,這些位置可能在不同的節(jié)點或者不同的存儲設(shè)備上。這就會導(dǎo)致每個進(jìn)程分別訪問矩陣文件去存數(shù)據(jù)或者取數(shù)據(jù)的時候,產(chǎn)生大量隨機(jī)的小 I/O。隨機(jī) I/O 對存儲系統(tǒng)是不夠友好的,如果存儲系統(tǒng)的設(shè)備是機(jī)械硬盤就更糟糕。
- 第二個問題是進(jìn)程協(xié)同問題。整個矩陣只有都計算完了之后才是有意義的,因此這些參與計算的進(jìn)程之間還需要有一個協(xié)同,等每一部分計算完了之后要告訴大家,我的運(yùn)算結(jié)束了。當(dāng)所有進(jìn)程的計算都結(jié)束了,數(shù)據(jù)寫到存儲系統(tǒng)里,才能認(rèn)為是整個過程結(jié)束了。這就需要一個進(jìn)程協(xié)同機(jī)制來保證。?
為了解決這個兩個問題,傳統(tǒng) HPC 里面提出了一個兩階段 I/O 的優(yōu)化方法,這個方法的核心的思想就是匯聚。
假如大家對存儲系統(tǒng)有一定了解的話,會有這樣的一個認(rèn)識,就是那些大的、順序的 I/O,對于整個存儲系統(tǒng)來說,是表現(xiàn)最好的。在 HPC 里面,兩階段 I/O 要做的就是想辦法把那些小 I/O 匯聚成大 I/O。具體是這樣做的,從那些參與計算的進(jìn)程里面去挑選出來一些 I/O 進(jìn)程,由這些進(jìn)程去負(fù)責(zé)存儲設(shè)備數(shù)據(jù)的讀寫,不同的進(jìn)程負(fù)責(zé)的部分不重疊,最好和存儲設(shè)備能夠一一對應(yīng)上。這樣其它進(jìn)程如果想要訪問數(shù)據(jù)的時候,會路由到具體負(fù)責(zé)的進(jìn)程上去處理,由這個進(jìn)程統(tǒng)一處理。在整個計算過程中,這些負(fù)責(zé) I/O 的進(jìn)程實際上是可以先把數(shù)據(jù)緩存在內(nèi)存里面的,然后等到整個計算完了之后,再把數(shù)據(jù)保存回文件,刷回到存儲設(shè)備中。這個中間里面產(chǎn)生的一些進(jìn)程協(xié)作的問題,也是由這個方法來完成的。通過在 MPI 框架中實現(xiàn)這個方法,HPC 把整個過程的細(xì)節(jié)對上層的計算隱藏掉了,整體上使用起來非常的簡單和高效。
在這個過程中,我們就可以歸納出傳統(tǒng)的 HPC 對存儲的一些要求。首先在接口上,需要一個文件接口(POSIX),文件接口能夠很好地支持多進(jìn)程的并發(fā)隨機(jī)讀寫。在這個文件接口之上,再去支持好上面說的兩階段 I/O,這就是 HPC 最常用的 MPI 框架 I/O 部分(MPI-I/O)做的事情。因此,HPC 的接口要求是 POSIX 文件接口和 MPI-I/O 框架支持。在一些很大規(guī)模的訓(xùn)練里面,對整個吞吐的要求也是非常高的,通常會達(dá)到數(shù)十 GB/s 甚至數(shù)百 GB/s。
最后就是在延時方面,因為這些計算包含的矩陣運(yùn)算會分為很多輪,一輪輪運(yùn)算直至收斂,所以數(shù)據(jù)保存和讀矩陣的耗時是非常關(guān)鍵的,反饋到存儲系統(tǒng)就是 HPC 對延時有很苛刻的要求。
?
1.3. AI HPC 中的存儲問題
AI HPC 實際上跟傳統(tǒng) HPC 相似的地方在于一個典型的計算也是分為很多輪。在每一輪計算中,不同的計算節(jié)點會去從存儲系統(tǒng)把數(shù)據(jù)先預(yù)讀上來,進(jìn)行一些預(yù)處理,預(yù)處理完了之后由 GPU 來進(jìn)行運(yùn)算。在這個讀的過程中,每個計算的節(jié)點其實只是負(fù)責(zé)了整個大的訓(xùn)練樣本集合中的一小部分。這個讀取工作實際上是通過訓(xùn)練框架內(nèi)置的 Data Loader 機(jī)制來完成。整個過程中存在大量的讀 I/O,如果樣本都很小,就是大量的小 I/O。
在大規(guī)模的訓(xùn)練中,訓(xùn)練任務(wù)會周期性地做一些狀態(tài)的保存,叫做 checkpoint,這里狀態(tài)的保存主要起到故障恢復(fù)的作用。如果一個訓(xùn)練的耗費(fèi)的時間非常長,在訓(xùn)練中間遇到一些機(jī)器故障重新做計算的代價就會很高。假如說有一些已經(jīng)保存好的狀態(tài)可以加載上來,接著這個狀態(tài)把丟失掉的數(shù)據(jù)重新算一遍,這樣會比完全重新計算要快很多。因此,在訓(xùn)練過程中產(chǎn)生的 checkpoint,可以減少需要故障恢復(fù)的數(shù)據(jù)量。這個過程以寫 I/O 為主,在訓(xùn)練中的占比較小。
盡管越來越多的框架開始支持對象存儲等接口類型,但這些接口形式使用門檻較高,被廣泛接受還需要時間。文件接口依然是這個領(lǐng)域最主流的接口形式,被數(shù)據(jù)科學(xué)家、平臺工程師、用戶熟悉。
通常在生產(chǎn)環(huán)境下面,我們的 GPU 資源是非常寶貴的,絕大部分的企業(yè)會想去提高GPU 的利用率,這個時候就需要有一個訓(xùn)練調(diào)度的平臺,來幫助我們做資源的調(diào)度方面的一些工作,優(yōu)化資源使用。在優(yōu)化資源的同時,這些調(diào)度平臺可以起到的另外一個作用是屏蔽掉存儲系統(tǒng)的細(xì)節(jié),簡化整個 AI 訓(xùn)練使用存儲的復(fù)雜度。當(dāng)下業(yè)界已經(jīng)公認(rèn)的一個發(fā)展趨勢就是使用 K8s 這樣的調(diào)度系統(tǒng)來完成 AI 訓(xùn)練的調(diào)度,這也就要求存儲系統(tǒng)能夠接入 K8s CSI 體系。
在 GPU 訓(xùn)練中,讀寫存儲系統(tǒng)工作通常是由操作系統(tǒng)內(nèi)核來完成的。具體落實的時候是內(nèi)核使用 CPU 先將數(shù)據(jù)拷貝到內(nèi)存里,GPU 使用數(shù)據(jù)的時候再拷貝到顯存中。硬件廠商如 NVIDIA 在探索的一個優(yōu)化是讓 GPU 直接去讀取存儲系統(tǒng),從而減少 CPU 和 GPU 間的這一次拷貝開銷,同時降低 CPU 使用率。這個技術(shù)叫 GPU Direct Storage(GDS),如果能夠支持它的話,能夠讓 GPU 訓(xùn)練在數(shù)據(jù)讀寫速度方面有更好的表現(xiàn)。不過目前這個技術(shù)在業(yè)界使用得并不廣泛,在未來它的發(fā)展前景怎么樣,我們還有待觀察。
歸納下來,AI HPC 對存儲接口的需求是 POSIX、K8s CSI,可選支持 GDS。
接口層面之外,不同的 AI 訓(xùn)練在負(fù)載方面有不同的特點,但是很多的 AI 訓(xùn)練會有海量小文件的需求。例如,在一些圖片相關(guān)的訓(xùn)練中,每一個圖片都很小,但是整個圖片的樣本集,假如展開來看的話會有非常多的小文件,一個樣本集文件數(shù)多達(dá)幾百萬上千萬都是有可能的。在整個的訓(xùn)練過程中,實際上對于那些樣本集里的圖片數(shù)據(jù)是不會做任何修改的,所以它對存儲系統(tǒng)的 I/O 需求實際上是以讀為主的。跟 HPC一樣,為了讀取的高效率,需要滿足高吞吐和低延時的要求。此外,部分訓(xùn)練涉及到海量小文件的問題,海量小文件的特點就是元數(shù)據(jù)請求占比較高,存儲系統(tǒng)的元數(shù)據(jù)性能至關(guān)重要。
?
1.4. HPDA 中的存儲問題
因為 HPDA 就是跟大數(shù)據(jù)結(jié)合的一類高性能計算,所以說它的整個特點就跟大數(shù)據(jù)一樣。例如,我們?nèi)ビ^察一個典型的 MapReduce 的任務(wù),會發(fā)現(xiàn)在 Map 階段,Map Task 會去存儲系統(tǒng)里面去把數(shù)據(jù)讀取出來,然后進(jìn)行運(yùn)算,整個一輪運(yùn)算的結(jié)束的 Reduce Task 會把產(chǎn)生的數(shù)據(jù)再存回存儲系統(tǒng)里面。在這一類的場景里面,最早大家都是去使用 Hadoop 自帶的 HDFS 來作為存儲系統(tǒng),隨著業(yè)界開始流行一些存算分離的架構(gòu),大家發(fā)現(xiàn),這一類計算使用對象存儲來運(yùn)行,成本更低,擴(kuò)展性更好。Hadoop 的客戶端在設(shè)計的時候就考慮了第三方存儲系統(tǒng)的兼容需求,存儲系統(tǒng)只要兼容 Hadoop 的存儲接口,也就是 HCFS,就可以很方便的被大數(shù)據(jù)體系所使用。
HPDA 整個負(fù)載特點是以大文件為主,對延時不是特別的敏感,但是對吞吐要求非常的高。
1.5. 高性能計算場景存儲需求的總結(jié)
現(xiàn)在可以簡單地對這三類高性能計算的場景做一個總結(jié)。
首先在性能方面,我們會發(fā)現(xiàn),這些計算對存儲的需求,絕大部分情況下是發(fā)生在一批計算前面數(shù)據(jù)加載的階段,和最后的數(shù)據(jù)保存階段,這兩個階段如果存儲性能跟不上的話,會導(dǎo)致 GPU、CPU 在那里等待,無事可做,空轉(zhuǎn)浪費(fèi)算力。GPU、CPU 在成本上來說是遠(yuǎn)高于存儲成本的,存儲一定要減少它們的等待時間。這些場景共性的要求是高吞吐,對一些 HPC 或者 AI HPC 的場景,還有額外的低延時要求。第二點是文件大小的方面。這里面 AI HPC 場景比較特殊,它有海量小文件的需求,海量小文件實際上對整個存儲系統(tǒng)的擴(kuò)展性以及元數(shù)據(jù)性能方面的挑戰(zhàn)是比較大的。第三點是接口方面。到目前為止,POSIX 文件接口還是最主流的。HCFS 是 POSIX的一個子集,滿足了 POSIX 要求后很容易開發(fā) HCFS SDK。HPC 比較特殊,除了完整的 POSIX 兼容性之外,還需要去適配 MPI-I/O 框架。第四點是對于所有存儲系統(tǒng)的一個通用需求。對于非常重要的數(shù)據(jù),我們有數(shù)據(jù)持久化要求,確保數(shù)據(jù)不會丟失。對于一些特殊的計算場景,這個要求可以放松,在一些多輪計算中,部分結(jié)果是中間生成的臨時結(jié)果,這些臨時結(jié)果可以通過計算重新生成。對于這些臨時的結(jié)果,可以選擇使用一些臨時存儲空間來存放,以換取更高的運(yùn)算速度,更低的成本。這種臨時存儲空間需求在 HPC 和 AI HPC 中比較普遍,存儲系統(tǒng)可以使用單副本來滿足。最后一點,也是大家去使用存儲系統(tǒng)的一個通用需求,就是希望在滿足性能需求的前提下,存儲這方面花的成本越低越好,當(dāng)下企業(yè)有很多的原始數(shù)據(jù)和歷史數(shù)據(jù)需要保存,這一點顯得更為重要。
?
2. 百度內(nèi)部的高性能存儲實踐
百度內(nèi)部高性能計算場景面臨的情況是非常復(fù)雜的。百度的高性能計算中,傳統(tǒng) HPC計算的比重是相對比較少的,主要是以 AI HPC 和 HPDA 為主。這些計算包含很多的業(yè)務(wù),包括自動駕駛、語音識別、廣告推薦之類,這些不同的業(yè)務(wù)有各自的特點,高吞吐、低延時、大文件、小文件的需求皆有。在計算硬件方面,也有很多不同的選擇,例如一些業(yè)務(wù)可能主要用 GPU 來做訓(xùn)練,另外有些業(yè)務(wù)主要用 CPU,百度內(nèi)部也有自研的一體機(jī)和類似于昆侖芯這樣的 AI 專用芯片。這就導(dǎo)致從計算側(cè)來看,百度內(nèi)部存儲無論是業(yè)務(wù)的種類、業(yè)務(wù)的規(guī)模,還是業(yè)務(wù)的復(fù)雜度,面臨的挑戰(zhàn)都是比較大的。
百度內(nèi)部實踐經(jīng)驗中,最核心的一點就是有一個統(tǒng)一的存儲底座來做數(shù)據(jù)的流轉(zhuǎn)中心。大家可以想一下,整個高性能計算的過程實際上是分為很多個環(huán)節(jié)的。比如說自動駕駛,要從很多的全國的道路采集路況信息,數(shù)據(jù)收集完了需要做一些預(yù)處理,例如給行人、機(jī)動車、交通標(biāo)示牌做標(biāo)注之類的。做完標(biāo)注之后,才是真正的訓(xùn)練過程,訓(xùn)練完了之后會產(chǎn)生一些需要部署到生產(chǎn)系統(tǒng)上的模型,所以還要去做模型的管理、模型的部署。假如這些數(shù)據(jù)分散在不同的存儲系統(tǒng)上的話,對使用效率和使用方便程度上來講,是一個比較大的挑戰(zhàn)。所以百度內(nèi)部使用了一個統(tǒng)一的存儲底座來簡化數(shù)據(jù)的管理和流轉(zhuǎn)。存儲底座的核心能力是高可靠、低成本、高吞吐。首先看可靠性,使用了統(tǒng)一的存儲底座之后,存儲底座是數(shù)據(jù)最可靠、甚至是唯一的數(shù)據(jù)來源,需要保證數(shù)據(jù)萬無一失。在這個基礎(chǔ)上,底座存儲的數(shù)據(jù)量非常之大,需要在成本方面需要做到比較優(yōu)。最后,它作為一個統(tǒng)一的數(shù)據(jù)流轉(zhuǎn)中心,需要有足夠的吞吐能力,能夠支撐很多的流程在上面并發(fā)運(yùn)行。在這個統(tǒng)一存儲底座的基礎(chǔ)之上,會去支持一些高性能計算常用的接口需求,包括POSIX 文件接口以及 HCFS 大數(shù)據(jù)接口。一些對性能有更高要求的一些業(yè)務(wù),愿意去做一些定制開發(fā)的話,它可以直接用存儲底座提供的 SDK。
?到了關(guān)鍵的訓(xùn)練環(huán)節(jié),也就是計算環(huán)節(jié),百度內(nèi)部采用了不同的運(yùn)行時解決方案來滿足業(yè)務(wù)多樣化的訴求,主要分為兩類:
- 第一類解決方案解決 AI 訓(xùn)練中存在的海量小文件問題。對于存儲底座來說,它首先要保證的是高吞吐和低成本,會采用一些相對比較廉價的存儲介質(zhì),雖然單個設(shè)備的能力較差,但規(guī)模上來之后就有了規(guī)模效應(yīng),可以提供很大的吞吐。但這也導(dǎo)致它在處理小文件的時候,在元數(shù)據(jù)方面以及 I/O 方面的性能是不太理想的,這個時候就需要有一些速度更快的解決方案作為彌補(bǔ)。在百度內(nèi)部,根據(jù)數(shù)據(jù)集的大小,業(yè)務(wù)可以有兩種選擇,包括本地盤和并行文件系統(tǒng)。如果數(shù)據(jù)集比較小,計算節(jié)點的本地盤足夠放下整個數(shù)據(jù)集,那訓(xùn)練任務(wù)完全就可以把數(shù)據(jù)先存到本地盤上,然后基于本地盤來做計算。在另外一些場景下面,本地盤的大小遠(yuǎn)遠(yuǎn)不夠存放下整個數(shù)據(jù)集,那這個時候就需要一個規(guī)模更大的共享文件系統(tǒng)來做這個事情,這是并行文件系統(tǒng)要解決的問題。這個并行文件系統(tǒng)會有自己獨(dú)立的集群,多租戶共享,支持 RDMA 網(wǎng)絡(luò)、NVMe SSD,軟硬件都做了很多的優(yōu)化,來保證在海量小文件場景下,能夠有比較好的元數(shù)據(jù)性能和 I/O 性能。
- 第二類解決方案針對那些訓(xùn)練時長非常長、重復(fù)較少的一些訓(xùn)練,這類訓(xùn)練主要的要求是能夠把數(shù)據(jù)源源不斷地從存儲底座讀取出來,吞吐比延時更重要。這個時候很多業(yè)務(wù)的選擇就是去直接訪問存儲底座,利用存儲底座比較好的高吞吐能力,來服務(wù)計算。
在整個使用過程中,還面臨一些關(guān)鍵的使用問題。例如,數(shù)據(jù)怎么在不同系統(tǒng)(存儲底座和并行文件系統(tǒng)、存儲底座和本地盤)之間做流轉(zhuǎn);在使用的過程中,怎么簡化不同類型存儲的掛載、卸載和初始化、容量分配等工作。這些工作對于不同的業(yè)務(wù)來說是一樣的,內(nèi)部的大規(guī)模分布式訓(xùn)練平臺,為用戶屏蔽掉了這些繁瑣的步驟,讓這些業(yè)務(wù)對整個存儲系統(tǒng)的使用,變得非常的簡單和高效。
?
3. 百度滄海高性能存儲解決方案
在百度內(nèi)部實踐的基礎(chǔ)上,孵化出了百度滄海存儲在高性能計算領(lǐng)域的整體解決方案。這個解決方案,和百度內(nèi)部的實踐是一樣的,由大容量、高吞吐、低成本的存儲底座,和更快的運(yùn)行時存儲 PFS、RapidFS 組成。
對象存儲已經(jīng)是業(yè)界共識的云上數(shù)據(jù)湖的事實標(biāo)準(zhǔn),滿足存儲底座的所有條件,同時還有豐富的生態(tài)。和原來百度內(nèi)部實踐的存儲底座相比,百度智能云的對象存儲 BOS 還具備分級存儲和智能生命周期能力。這兩個能力可以讓數(shù)據(jù)根據(jù)訪問頻次等條件,自由地在不同成本的層級間流轉(zhuǎn),達(dá)到整體成本最優(yōu)的狀態(tài)。舉個例子,現(xiàn)在經(jīng)常要使用的一些數(shù)據(jù)可以放到標(biāo)準(zhǔn)存儲里面,這樣的話它在訪問的時候速度是比較快的,隨著這些數(shù)據(jù)逐漸轉(zhuǎn)冷,可能很長時間都不會再用到,那就可以把這些數(shù)據(jù)通過生命周期策略,自動地往更低頻、更廉價的存儲分級去沉降,最后可以一直沉降到磁帶介質(zhì)的歸檔存儲上,以此來達(dá)到一個訪問性能、成本之間比較好的均衡。運(yùn)行時存儲 PFS、RapidFS 的最大特點就是這兩個產(chǎn)品是近計算部署的,主要目的是為了讓它們能夠達(dá)到最好的 I/O 性能。這兩個系統(tǒng)還需要解決和對象存儲數(shù)據(jù)湖之間的高效數(shù)據(jù)流轉(zhuǎn)的問題,以及在調(diào)度平臺上如何更簡單地使用它們的問題。接下來簡單地介紹一下這兩個系統(tǒng)。
?
3.1 并行文件存儲 PFS?
PFS 是一個典型的并行文件系統(tǒng),和業(yè)界的 Lustre、GPFS 這些系統(tǒng)在架構(gòu)上是比較接近的。系統(tǒng)主要的一個特點就是整個 I/O 路徑會非常的短,請求從內(nèi)核態(tài)客戶端出來之后,根據(jù)它的類型的,是元數(shù)據(jù)的請求還是 I/O 的請求,直接發(fā)給對應(yīng)的元數(shù)據(jù)節(jié)點 MDS 或者數(shù)據(jù)節(jié)點 OSS 處理。這樣,對于讀 I/O 來說,I/O 路徑只有一跳。這個是軟件架構(gòu)上的性能保證,在硬件上我們同樣有一些保證。PFS 采用托管架構(gòu)將系統(tǒng)部署到用戶 VPC 的虛機(jī)或物理機(jī)上,讓它在整個物理網(wǎng)絡(luò)上和計算節(jié)點離得非常近,這里的物理網(wǎng)絡(luò)可能是 RDMA 或高速 TCP。PFS 通過這些軟硬件上的多重保證,來確保整個系統(tǒng)的性能是比較高的。?
?
3.2 分布式緩存加速 RapidFS
RapidFS 跟 PFS 一個最大的差別就是,PFS 使用了獨(dú)立的存儲節(jié)點進(jìn)行部署,對于客戶來說,仍然有一些成本上的付出。但是對于一些小規(guī)模的訓(xùn)練,計算節(jié)點本地有一些冗余的內(nèi)存資源、磁盤資源,假如能把這些資源利用起來,對客戶來說,就不需要付出額外的經(jīng)濟(jì)代價,同時還能享受到比較好的性能。RapidFS 就是為了解決這樣一類場景而實現(xiàn)的一個系統(tǒng),它的定位是一個緩存加速系統(tǒng),原理是將用戶計算節(jié)點上的冗余資源,組織成一個小的 P2P 緩存來加速計算。RapidFS 加速的能力主要來自于兩個方面:
- 第一個加速效果來自層級命名空間(namespace)。命名空間在存儲系統(tǒng)里負(fù)責(zé)組織文件和目錄之間的關(guān)系以及保存屬性信息,文件系統(tǒng)的元數(shù)據(jù)也是指這一部分。層級命名空間是 POSIX 使用的命名空間形式,就像一棵倒掛著生長的樹,從根目錄開始,每一個文件或目錄都屬于一個父目錄。平坦命名空間是對象存儲使用的命名空間,文件和目錄彼此是平等獨(dú)立的,不存在父子關(guān)系,這個設(shè)計可以讓命名空間的擴(kuò)展性能更好。對于用戶來說,想要通過 POSIX 的方式(這是很常見的用法)去訪問對象存儲,會有很大的元數(shù)據(jù)操作的放大。為了解決這個問題,RapidFS 內(nèi)置了一個高效的層級命名空間,來做 BOS 命名空間的緩存。
- 第二個加速效果來自數(shù)據(jù)緩存。針對于 BOS 上數(shù)據(jù)訪問比較慢的問題,RapidFS 將比較熱的數(shù)據(jù)緩存到用戶提供的冗余內(nèi)存和磁盤上面,這樣等用戶去訪問的時候,訪問路徑很短。
3.3 高效數(shù)據(jù)流轉(zhuǎn)
有了這兩類運(yùn)行時存儲之后,需要解決怎么在這兩個系統(tǒng)和存儲底座之間做數(shù)據(jù)流轉(zhuǎn)的問題。實際上我們是通過兩種機(jī)制來滿足的:
- 第一種機(jī)制是生命周期,這一機(jī)制跟對象存儲分級存儲體系類似。在一些場景如 HPC 中,業(yè)務(wù)的整個訪問入口主要是文件系統(tǒng),也就是 PFS。很多數(shù)據(jù)在 PFS 里產(chǎn)生之后,逐漸轉(zhuǎn)冷,將這部分?jǐn)?shù)據(jù)存儲到到更低成本的系統(tǒng)或介質(zhì)上是一個普遍訴求。在我們的方案里,PFS 可以通過生命周期的功能,把近期內(nèi)不再使用的數(shù)據(jù),自動地轉(zhuǎn)移到對象存儲里面,讓用戶能夠把成本降下來。用戶去訪問的時候,PFS 又把數(shù)據(jù)自動地給加載回來。這樣用戶自己其實是不需要去關(guān)心數(shù)據(jù)到底是在對象存儲還是在 PFS 里面,他只需要關(guān)心哪些目錄需要開啟生命周期功能。在我們的規(guī)劃里,RapidFS 后續(xù)將推出的 Block 模式也具備類似的能力,訪問入口在 RapidFS,熱數(shù)據(jù)緩存在計算節(jié)點本地,數(shù)據(jù)的持久化和冷數(shù)據(jù)由對象存儲負(fù)責(zé)。
- 另外一個機(jī)制是 Bucket Link。Bucket Link 的數(shù)據(jù)流走向跟生命周期正好是反向的。很多情況下,用戶的數(shù)據(jù)實際上已經(jīng)在對象存儲里面了,例如自動駕駛這樣的業(yè)務(wù),它的數(shù)據(jù)是線下采集的一些路測數(shù)據(jù),這些數(shù)據(jù)通過對象存儲服務(wù)提供的工具上會傳到對象存儲里,訓(xùn)練時候的數(shù)據(jù)源實際上就是對象存儲。但如果想要用 PFS 或者 RapidFS 來支撐訓(xùn)練,就需要高效地把數(shù)據(jù)搬過來。Bucket Link 要解決的就是這個問題,它本質(zhì)上是將數(shù)據(jù)搬運(yùn)的能力內(nèi)置到了存儲系統(tǒng)里面,用戶只要通過一個很簡單的命令,或者說一個界面的操作,就能夠把 PFS 的一個目錄或者 RapidFS 的一個命名空間,和對象存儲里面的一個路徑做一個綁定,這個綁定就是 Bucket Link。綁定后,PFS 和 RapidFS 可以自動地幫用戶完成數(shù)據(jù)的加載,以及數(shù)據(jù)的預(yù)熱。這樣等到用戶訓(xùn)練真正開始運(yùn)行的時候,PFS 和 RapidFS 里的數(shù)據(jù)已經(jīng)準(zhǔn)備好了,任務(wù)直接可以運(yùn)行。?
?
3.4 統(tǒng)一調(diào)度?
Bucket Link 的能力可以手動調(diào)用命令去使用,但是很多情況下,對客戶來說更方便的使用方法是去結(jié)合作業(yè)調(diào)度器。前面我們已經(jīng)提到了,現(xiàn)在越來越多的客戶會使用K8s 作為他們的作業(yè)調(diào)度系統(tǒng),因此我們選擇將 Bucket Link 整合到 K8s 中。業(yè)界有一個開源項目叫 Fluid,它可以將整個訓(xùn)練的過程分成了兩個階段,一個階段是用來做數(shù)據(jù)加載,另外一個階段才是用來做真正的訓(xùn)練。這兩個階段拆分之后,在不同的任務(wù)之間 pipeline 并發(fā)起來。舉個簡單的例子,整個系統(tǒng)可能只有四張 GPU 卡,A 訓(xùn)練跟 B 訓(xùn)練都需要去用這四張卡來做訓(xùn)練,那在 A 訓(xùn)練跑 GPU 任務(wù)的時候,完全可以讓 B 訓(xùn)練提前做數(shù)據(jù)預(yù)加載的工作,將數(shù)據(jù)提前預(yù)熱到 PFS 或者 RapidFS 里。等到 A 訓(xùn)練任務(wù)完成的時候,就直接可以讓調(diào)度器把 B 訓(xùn)練跑起來了。整體上看到的效果就是 B 的數(shù)據(jù)加載階段被隱藏掉了,加載過程跟計算過程分階段 pipeline 化了。對于那些訓(xùn)練任務(wù)很多的用戶,GPU 等待時間變少了,利用率得到了很大的提高。PFS 和 RapidFS 統(tǒng)一都支持了 Fluid,在使用上體驗接近,可靈活替換。在這個基礎(chǔ)上,我們也會支持一些很細(xì)分的策略。那些對 I/O 延時不太敏感,但對元數(shù)據(jù)比較敏感的一些訓(xùn)練,可以只讓它加載元數(shù)據(jù)。對元數(shù)據(jù)和數(shù)據(jù)訪問要求都比較高的一些訓(xùn)練,在加載元數(shù)據(jù)的同時預(yù)熱數(shù)據(jù)。所有的這些技術(shù)手段,目的都是讓用戶感受到比較好的使用體驗。?
?
3.5 測試數(shù)據(jù)?
我們來簡單看一下 PFS 和 RapidFS 在實際支持用戶訓(xùn)練時候的效果。在這個例子里,有三組數(shù)據(jù),分別是基于 RapidFS、PFS、對象存儲直接來做 GPU 訓(xùn)練。可以看出,當(dāng)使用 RapidFS 或 PFS 使用 Bucket Link 做完數(shù)據(jù)預(yù)熱之后,整個訓(xùn)練期間的 GPU 利用率直接打滿。基于對象存儲直接來做這個訓(xùn)練的話,中間很大一部分時間是消耗在數(shù)據(jù)的讀取上,整個 GPU 利用率在一個非常低的水位上。通過這樣一個實驗,我們大致能夠看到 RapidFS 跟 PFS 在高性能計算加速這一塊的效果。?
?
4. 客戶案例
最后我們來介紹一個典型客戶的案例。
大家都知道百度是國內(nèi)最大的自動駕駛方案廠商,也具備將自動駕駛整體解決方案對外輸出的能力。因此有一些造車新勢力的企業(yè),在百度智能云上使用自動駕駛的整體解決方案,其中就包含百度滄海·存儲提供的解決方案。
在圖示的案例里,客戶的一些采集車線下做路測,不斷地通過車上的攝像頭去采集路況數(shù)據(jù)。這些數(shù)據(jù)通過百度智能云提供的一個叫“月光寶盒”的專門硬件存儲下來。采集到的數(shù)據(jù)客戶可以選擇兩種方式上傳到對象存儲 BOS 里面。第一種方式通過網(wǎng)絡(luò)的方式來傳輸,這種方式的速度受限于網(wǎng)絡(luò)帶寬,實際上整個吞吐不太高。另外還有一種方式可能大家看來會是很原始,就是把通過物流把月光寶盒寄回來。
月光寶盒這個設(shè)備可以簡單的理解為一個比較大的移動硬盤,當(dāng)然它會比普通的移動硬盤盤數(shù)更多,可靠性更高。用戶采集了一批數(shù)據(jù)之后,可以直接把月光寶盒郵寄到百度智能云的數(shù)據(jù)中心,再通過內(nèi)部的網(wǎng)絡(luò)把這些數(shù)據(jù)上傳到對象存儲 BOS。這樣的解決方案,能夠保證用戶在 10 個小時之內(nèi)能夠完成 1PB 數(shù)據(jù)的上傳,遠(yuǎn)比使用網(wǎng)絡(luò)上傳的方式要快很多。所以說這種方案雖然看起來可能比較原始,但是確實很高效。
客戶將他的數(shù)據(jù)沉淀到對象存儲 BOS 之后,基于這些數(shù)據(jù)來做后續(xù)的訓(xùn)練,PFS 就是主要用來支撐它整個 GPU 集群訓(xùn)練的產(chǎn)品。整個并行文件存儲 PFS 集群大概是數(shù) PB 容量,只有在訓(xùn)練的時候才會把需要的數(shù)據(jù)加載進(jìn)來,高效支持了數(shù)千卡 GPU 集群的訓(xùn)練。
用戶實際上還用了很多百度智能云提供的一些其它能力,包括在 IaaS 側(cè)、PaaS 側(cè)的BBC、BCC、MongoDB 等產(chǎn)品,以及百度智能云針對 AI 領(lǐng)域的一些 SaaS 服務(wù)。這些能力其實都是在百度內(nèi)部經(jīng)過大規(guī)模實踐之后,才在百度智能云產(chǎn)品化出來的。
客戶訓(xùn)練的結(jié)果又會反饋到路測的流程上,形成了一個完整的閉環(huán),一輪輪地去做數(shù)據(jù)的采集、訓(xùn)練和方案的迭代。