文獻標識碼: A
文章編號: 0258-7998(2012)05-0128-04
近年來,Lustre作為一個開源的高性能分布式集群文件系統(tǒng),以其PB級的共享存儲容量和上百吉字節(jié)每秒的聚合 I/O帶寬被廣泛應(yīng)用于HPC領(lǐng)域。有數(shù)據(jù)[1]表明Lustre在HPC領(lǐng)域占有最大的市場份額,已成為構(gòu)建HPC集群的事實上的標準。將Lustre引入到傳統(tǒng)的MPI集群解決I/O瓶頸,可提升并行計算速度。但是簡單地將Lustre移植到MPI集群中并不能獲得預(yù)期的效果。其主要原因是,運行MPI的并行程序需要進行大量的I/O訪問,而在這些I/O訪問中基于小數(shù)據(jù)(細粒度)的I/O訪問往往占據(jù)著相當(dāng)大的比率,雖然Lustre能在連續(xù)大數(shù)據(jù)(粗粒度)傳輸上達到很高的I/O帶寬,但在不連續(xù)小數(shù)據(jù)傳輸上并沒有獲得顯著的性能提升。當(dāng)大量小數(shù)據(jù)I/O頻繁訪問時,就會使該文件系統(tǒng)的整體性能迅速下降,以至實際I/O帶寬遠低于所提供的最大帶寬。
為解決這一問題,通常的方法是在Lustre的上層加入一個并行I/O庫,通過該庫將多個不連續(xù)小數(shù)據(jù)塊的I/O操作轉(zhuǎn)化為對并行文件系統(tǒng)中的少量連續(xù)大數(shù)據(jù)塊的實際I/O操作,最大程度地利用并行文件系統(tǒng)所提供的帶寬,減少I/O瓶頸對程序性能的影響,在庫的級別上優(yōu)化并行I/O的訪問效率。本文提出了一種基于MPI-IO庫(并行I/O庫)編程接口的改進方案,以保證在小數(shù)據(jù)整合為大數(shù)據(jù)的過程中進一步減少進程間的通信量和時間消耗,從而提升集群并行效率,為傳統(tǒng)MPI集群的升級改造提供新的思路或新的方法。
1 Lustre文件系統(tǒng)性能介紹
Lustre是面向集群的存儲架構(gòu),是基于Linux平臺的開源集群(并行)文件系統(tǒng)。由于其提供了與POSIX兼容的文件系統(tǒng)接口,從而使其擴展了應(yīng)用領(lǐng)域。Lustre擁有高性能和高擴展性兩個最大特征。高性能是指它能夠支持數(shù)萬客戶端系統(tǒng)、PB級存儲容量和數(shù)百GB的聚合I/O吞吐量;高擴展性是指由于Lustre是Scale-Out存儲架構(gòu),由此可以借助強大的橫向擴展能力,只要以增加服務(wù)器的方式便可擴展系統(tǒng)總存儲容量和系統(tǒng)總性能。
Lustre文件系統(tǒng)主要由元數(shù)據(jù)服務(wù)器MDS(Metadata Server)、對象存儲服務(wù)器OSS(Object Storage Server)、客戶端(Lustre Client)三部分組成。MDS用于存儲數(shù)據(jù)描述信息,管理命名空間和目標存儲地址;OSS進行實際的數(shù)據(jù)存儲,提供文件I/O服務(wù);Lustre Client則運行Lustre文件系統(tǒng),并作為集群計算端與MDS和OSS進行信息交互[2]。如圖1所示。
由于Lustre設(shè)計的初衷是要提高數(shù)據(jù)訪問的并行性和擴展聚合I/O帶寬,所以在設(shè)計過程中廣泛采用了元數(shù)據(jù)與數(shù)據(jù)分離、數(shù)據(jù)分片策略、數(shù)據(jù)緩存和LNET網(wǎng)絡(luò)等技術(shù)。而在這些設(shè)計中,數(shù)據(jù)分片設(shè)計和后端改進的EXT3文件系統(tǒng)非常適合大數(shù)據(jù)連續(xù)I/O訪問,所以Lustre在大數(shù)據(jù)應(yīng)用中其性能表現(xiàn)得非常好。但對于不連續(xù)小數(shù)據(jù)I/O而言,由于Lustre在讀寫文件前需要與MDS進行交互,以獲得相關(guān)的屬性和對象位置信息,從而增加了一次額外的網(wǎng)絡(luò)傳輸和元數(shù)據(jù)訪問的開銷(與傳統(tǒng)本地文件系統(tǒng)相比)。若有大量頻繁的小數(shù)據(jù)讀寫時,Lustre客戶端上Cache的作用將失效,其命中率也會大大降低。如果數(shù)據(jù)小于物理頁大小,則還會產(chǎn)生額外的網(wǎng)絡(luò)通信量,小數(shù)據(jù)訪問越頻繁,則網(wǎng)絡(luò)開銷也就越大,進而影響Lustrer的總體I/O性能。OST(對象存儲目標服務(wù)器)后端雖然采用了改進的EXT3文件系統(tǒng),但它對小數(shù)據(jù)的讀寫性能存在先天的缺陷,其元數(shù)據(jù)訪問效率也不高,且磁盤尋址延遲和磁盤碎片問題嚴重。所以,Lustre的設(shè)計決定了它對小數(shù)據(jù)I/O的表現(xiàn),其實際I/O帶寬遠低于所提供的最大帶寬。
因此Lustre集群及其并行架構(gòu)非常適合眾多客戶端并發(fā)進行大數(shù)據(jù)讀寫的場合,但對于不連續(xù)小數(shù)據(jù)的應(yīng)用是不適合的,尤其是海量小文件應(yīng)用LOSF(Lots Of Small Files)。
2 MPI-IO對并行I/O的實現(xiàn)
MPI-IO是一個并行I/O庫,作為 MPI-2 規(guī)范的一部分,提供了執(zhí)行可移植的、用戶級的I/O 操作接口。MPI可以通過該接口在文件和進程間傳送數(shù)據(jù),如圖2所示。ROMIO是MPI-IO的一個具體實現(xiàn),而ADIO是位于并行文件系統(tǒng)和上層I/O庫ROMIO之間的軟件層,它的作用是使得上層并行I/O庫的實現(xiàn)具有更好的移植性和更好的I/O訪問效率。由于ADIO可以在不同的并行文件系統(tǒng)上實現(xiàn),提供了一組最基本的并行I/O訪問的函數(shù),所以I/O庫只需要在ADIO上實現(xiàn)一次,就可以通過ADIO實現(xiàn)對所有底層文件系統(tǒng)的訪問。一些特定的并行文件系統(tǒng)的優(yōu)化通常也在ADIO層上實現(xiàn),所以ADIO的實現(xiàn)使得上層庫可以透明訪問底層并行文件系統(tǒng),而不必考慮底層并行文件系統(tǒng)方面的細節(jié)。正基于此,本文所提出的改進策略也是在ADIO上實現(xiàn)的[3]。
MPI-IO可分為非集中式(noncollective I/O)和集中式(collective I/O)兩種I/O操作。
非集中式I/O操作,是MPI-IO的普通I/O操作方式。在此操作下,若每個進程訪問文件中存放位置不連續(xù)的小片數(shù)據(jù)時,往往是對每一個小片連續(xù)的數(shù)據(jù)使用單個獨立函數(shù)來讀寫數(shù)據(jù),就像在Unix或Linux中一樣,所以這種方法I/O延遲較大,系統(tǒng)開銷也較大。但對于連續(xù)大數(shù)據(jù)的讀寫,此種方式可以利用操作系統(tǒng)緩存和Lustre數(shù)據(jù)分片等技術(shù),充分發(fā)揮并行I/O的優(yōu)勢。
而對于集中式I/O操作,由于集中式I/O具有并行程序的對稱性,當(dāng)I/O發(fā)生時集群中所有節(jié)點均運行到各自子進程的相同位置,所以各子進程會在一個很短的時間間隔內(nèi)各自發(fā)出I/O 請求,集中式I/O便合并這些小的讀寫請求,使之整合成為大的讀寫請求,從而減少磁盤磁頭移動和I/O次數(shù),提高I/O讀寫速度。本文的改進型編程接口也正是基于此類I/O方式將多個不連續(xù)的小數(shù)據(jù)I/O整合為少量的大數(shù)據(jù)I/O,進而再利用底層的Lustre并行文件系統(tǒng)對大數(shù)據(jù)I/O的優(yōu)勢,使得集群的整體并行效率得到提升。集中式I/O有很多實現(xiàn)方案,ROMIO是采用基于Client-level的兩階段法來實現(xiàn)集中式I/O的。
兩階段法通過分析集中式I/O請求對數(shù)據(jù)的總體需求,將一次I/O操作分成兩個階段來完成。第一個階段是所有計算進程交換彼此I/O信息,確定每個進程的文件域,從磁盤上讀取相應(yīng)I/O數(shù)據(jù);第二個階段是按照應(yīng)用需求將緩沖區(qū)的數(shù)據(jù)交換分配到各進程的用戶緩沖區(qū),寫操作與讀操作類似。在這兩個階段中,進程之間需要進行相互通信,同步同一通信域中的相關(guān)進程的數(shù)據(jù)信息,從而得到程序總體的I/O行為信息,以便整合各個進程獨立的I/O請求。如圖3所示。
第一階段:
(1) 確定參加讀操作的通信域中所有進程,并進行同步;
(2) 確定每個進程各自需要讀取的一個包含所請求數(shù)據(jù)的連續(xù)的文件區(qū)域;
(3) 每個進程根據(jù)自己的文件區(qū)域進行I/O訪問,并將這些數(shù)據(jù)存放在一個臨時緩沖中,同步所有進程到每個進程的I/O操作結(jié)束。
第二階段:
(1) 進行I/O數(shù)據(jù)的置換,將緩存中數(shù)據(jù)發(fā)送給目標進程;
(2) 同步所有進程到數(shù)據(jù)置換結(jié)束。
寫操作類似于讀操作。兩階段I/O整合了多個進程所請求的數(shù)據(jù)范圍,訪問到稠密的數(shù)據(jù)區(qū)域的可能性比較大,因此對于非連續(xù)數(shù)據(jù)分布比較分散情況,該算法有明顯的性能優(yōu)勢。但是,兩階段I/O的性能很大程度上依賴于MPI所提供的高效的數(shù)據(jù)傳遞機制,即消息傳遞機制。如果MPI無法提供比底層文件的聚合帶寬更快的速度,那么在兩階段I/O中數(shù)據(jù)傳遞所帶來的額外開銷將會大大降低該I/O方式的性能[4]。
3 改進的并行I/O編程接口
從上述分析可知,MPI-IO在整個集群系統(tǒng)中起到了承上啟下的作用,向上連接MPI計算系統(tǒng),向下連接Lustre并行文件系統(tǒng),所以其效率的高低一直影響到集群的整體并行I/O效率。為此,本文所提方案需要對以下三個方面進行改進。
(1) 如何界定數(shù)據(jù)塊的大小
在Linux 32 bit的操作系統(tǒng)中,一個頁面大小為4 KB,同時也是Lustre網(wǎng)絡(luò)傳輸?shù)幕締挝?。由參考文獻[4]可知,當(dāng)數(shù)據(jù)大小不到一頁或不同進程同時讀寫一個頁面中數(shù)據(jù)的時候,Lustre的I/O性能最差,甚至不如傳統(tǒng)的本地文件系統(tǒng);若數(shù)據(jù)塊的大小不足一個條塊(數(shù)據(jù)分片),則客戶端每次讀寫只與一個OST交互信息,沒有從真正意義上實現(xiàn)Lustre并發(fā)I/O的功能。
所以如何界定數(shù)據(jù)塊的大小,是提高系統(tǒng)并行效率的關(guān)鍵。本文依據(jù)參考文獻[4]所提供的實驗數(shù)據(jù),設(shè)定Lustre條塊大小為64 KB,若數(shù)據(jù)塊小于該值,則視為小數(shù)據(jù),按本文改進的集中式MPI-IO編程接口操作;若數(shù)據(jù)塊大于該值,則視為大數(shù)據(jù),按非集中式MPI-IO接口操作。
(2) 采用直接I/O模式以減少內(nèi)核消耗
Lustre文件系統(tǒng)底層采用Portals協(xié)議進行數(shù)據(jù)傳輸,上層則連接Linux操作系統(tǒng)的VFS(虛擬文件系統(tǒng))。應(yīng)用程序所有的I/O操作都必須通過Linux的VFS才能進入Lustre。在Linux操作系統(tǒng)中,讀寫模式分為文件緩存(Cache)模式和直接(Direct)模式。
對于Lustre文件系統(tǒng)而言,由于該文件系統(tǒng)是以頁面為I/O的基本單位,所以當(dāng)n個進程去讀取僅需一個頁面的數(shù)據(jù)流量時,若采用緩存機制,則實際系統(tǒng)需要n個頁面的I/O流量才可完成,而隨著I/O請求的增加,這種額外的開銷將會越來越大;而對于寫操作,緩存機制在小數(shù)據(jù)I/O的問題則更加突出。在寫操作時,由于每個進程必須獲得該頁面上的文件鎖才能進行,以保證對這個文件寫操作的獨占性。但是當(dāng)一個進程獲得鎖后,其他進程只有等待該進程結(jié)束操作,所以對于同一個頁面的寫操作是串行的,系統(tǒng)不能發(fā)揮程序的并行作用而造成性能下降。并且,當(dāng)數(shù)據(jù)塊小于4 KB時(不足一個頁面),文件緩存的作用已經(jīng)不明顯,反而使得I/O調(diào)用的開銷越來越突出。因此, Lustre在非連續(xù)小數(shù)據(jù)I/O時,采用可以繞過系統(tǒng)緩存的直接I/O方式,直接將文件數(shù)據(jù)傳遞到進程的內(nèi)存空間則是一個可行的辦法。
(3) 減少集中式I/O第一階段的通信量
由前述可知,MPI-IO中的集中式I/O操作是采用兩階段法來進行的。該算法第一階段,通信域中所有進程同步操作方式采用廣播的形式,即每個進程的數(shù)據(jù)信息通過廣播的方式發(fā)送給通信域里的所有進程。也就是說,若有n個進程參與此次集中I/O操作,則整個過程中進程間需要n×(n-1)次點對點通信才能完成。這樣,隨著集群節(jié)點數(shù)的增加, 進程間的通信次數(shù)勢必會給I/O性能造成較大影響。所以,本文的優(yōu)化方案就是以減少進程間的通信量為目的,盡量減少進程間的通信次數(shù),以提高整體的I/O性能。這里,選取通信域中的一個進程作為主進程,通過它從其他進程收集各自的I/O信息進行相關(guān)的計算,并匯總整合本通信域中的所有I/O信息,再將其進行廣播,以達到進程間I/O信息同步的目的。若還是n個進程參與此次集中式I/O操作,則進程間的點到點通信次數(shù)將會降到2×(n-1)次。顯然,改進后的策略可以明顯降低進程之間的通信次數(shù),進而提高了整個集中操作的I/O性能。
4 實驗與分析
為驗證改進方案的可行性,在傳統(tǒng)的MPI集群上做了相應(yīng)的測試。測試環(huán)境為7個節(jié)點的集群系統(tǒng)(3臺OST,3臺客戶端,1臺MDS),每個節(jié)點包含一顆PIV處理器和2 GB內(nèi)存,40 GB的硬盤,操作系統(tǒng)采用Redhat Linux Enterprise 5(內(nèi)核為2.6.18),并行集群軟件為MPICH2.1,并行文件系統(tǒng)為Lustre 1.0.2。在測試程序中,在3個客戶端上同時運行3個進程讀寫一個文件的不同部分,測試文件為2 GB,其他的什么都不做,來測試改進前后的I/O 讀寫帶寬(改進前的讀寫方式為Lustre系統(tǒng)的普通讀寫方式)。
如圖4所示,先分析改進前Lustre系統(tǒng)的讀寫情況:數(shù)據(jù)塊為64 KB時,由于大部分RPC數(shù)據(jù)包中都包含了數(shù)十個頁,從而減少了I/O調(diào)用的次數(shù),效率達到最高;而當(dāng)數(shù)據(jù)塊小于64 KB(一個分片的大?。r,此時客戶端每次讀寫只能與一個OST交互信息,從而無法使用Lustre分片技術(shù)的并發(fā)功能,造成這一階段讀寫性能不佳;而當(dāng)數(shù)據(jù)塊大小為4 KB或者小于4 KB時,性能則快速下降,特別是寫操作,性能下降得更為嚴重,這主要是因為數(shù)據(jù)塊的大小不足1個頁面(4 KB),此時大部分的RPC數(shù)據(jù)包僅僅包含1個頁面而導(dǎo)致I/O效率不高,特別是在不同進程同時讀寫一個頁面中的數(shù)據(jù)的時候,則性能更糟。
由于改進后的方案采用了MPI-IO中的改進集中式操作和直接I/O技術(shù),使得數(shù)據(jù)塊在64 KB以下區(qū)段性能差異較大。但對于數(shù)據(jù)塊大于64 KB時,改進前后的差異不大,這是因為改進后的編程接口將大于64 KB的數(shù)據(jù)包均視為大數(shù)據(jù),不做修改,所以與改進前基本一致;對于數(shù)據(jù)包小于64 KB時,改進后的讀寫明顯放緩了I/O讀寫下降的速度,且讀操作和寫操作的速度基本持平,這主要是因為改進后的方案中使用了MPI-IO中的改進集中式操作,由于MPI-IO中可以使用單個函數(shù)來訪問非連續(xù)數(shù)據(jù),且可多次使用,同時MPI-IO也允許一組進程在同一時間訪問一個普通文件,在進行多次讀寫時,I/O的訪問開銷不但可以降低,而且還可將定義開銷分攤到各次訪問, 從而改善了小數(shù)據(jù)I/O操作的性能。
總之,基于Lustre的MPI-IO編程接口的改進方案是可行的。在該機制下構(gòu)建的MPI集群系統(tǒng)能夠有效解決I/O瓶頸,提升并行計算速度,與傳統(tǒng)的MPI集群相比性能提高空間很大。但是由于研究剛剛起步,還需要在總結(jié)現(xiàn)有不足的基礎(chǔ)上,繼續(xù)實踐、改進和完善。
參考文獻
[1] 錢迎進,金士堯,肖儂. Lustre文件系統(tǒng)I/O鎖的應(yīng)用與優(yōu)化[J]. 計算機工程與應(yīng)用, 2011,47(03):1-5.
[2] BRAAM P J. Lustre: A scable, high-performance file systme[M]. Lustre Whitepaper Version 1.0, 2002.
[3] 劉輝, 胡靜, 王振飛,等.MPI-2中的并行I/O的使用分析[J].計算機工程, 2003,29(2):229-232.
[4] 林松濤. 基于Lustre文件系統(tǒng)的并行I/O技術(shù)研究[D].國防科學(xué)技術(shù)大學(xué), 2004.