王晨曦 呂 方 崔慧敏 曹 婷 John Zigman 莊良吉 馮曉兵
1(計算機體系結(jié)構(gòu)國家重點實驗室(中國科學(xué)院計算技術(shù)研究所) 北京 100190)2(中國科學(xué)院大學(xué) 北京 100049)3(澳大利亞野外機器人中心(悉尼大學(xué)) 澳大利亞悉尼 2006)4(數(shù)學(xué)工程與先進(jìn)計算國家重點實驗室 江蘇無錫 214125)(wangchenxi@ict.ac.cn)
隨著數(shù)據(jù)中心、內(nèi)存數(shù)據(jù)庫、內(nèi)存計算的發(fā)展,需要處理的數(shù)據(jù)量急劇增加.企業(yè)為了快速響應(yīng)用戶的需求,需要對數(shù)據(jù)進(jìn)行實時處理,因此將大量的數(shù)據(jù)置于隨機讀寫性能良好的內(nèi)存中,以求降低開銷極大的磁盤IO帶來的性能損失[1].而目前使用的DRAM內(nèi)存技術(shù)受限于工藝瓶頸,其存儲密度難以繼續(xù)增加,功耗持續(xù)升高,同時其價格也難以繼續(xù)降低[2],阻礙了內(nèi)存計算規(guī)模的繼續(xù)增長.為了解決這些問題,一類新型的內(nèi)存結(jié)構(gòu)——非易失性內(nèi)存(non-volatile memory, NVM),逐漸獲得了研究人員的關(guān)注.非易失內(nèi)存所具有的存儲密度大、靜態(tài)功耗低、價格便宜等特性[3]可以很好地滿足內(nèi)存計對內(nèi)存容量持續(xù)增加的需求.然而,目前比較實用的非易失性內(nèi)存,如PCM(phase change memory)等,其延遲、帶寬等性能方面和DRAM(dynamic random access memory)之間有一定差距.因此,如何利用NVM來解決內(nèi)存計算對內(nèi)存容量快速增長的需求,是一個重要的研究問題.
Spark[4]是一種基于JVM運行、被業(yè)界廣泛采用的分布式內(nèi)存計算系統(tǒng).其將計算的中間結(jié)果和一些容錯信息存儲在內(nèi)存中,以加速計算、增強容錯性.因此,其對內(nèi)存的需求量隨著計算規(guī)模擴大而快速增加.但是由于DRAM的工藝瓶頸,內(nèi)存容量無法滿足其計算需求,此時便會造成應(yīng)用的性能快速下降.此時,造成Spark性能下降的主要原因在于內(nèi)存不足時、對磁盤的頻繁使用和Java Heap無法滿足計算規(guī)模時造成的頻繁GC(garbage collection)行為.同時,由于Spark自身的數(shù)據(jù)使用特點和當(dāng)前GC策略的不匹配[5],也加重了單次GC的開銷.此時,GC開銷甚至占據(jù)了程序運行時間的50%[5-6].
為了解決DRAM工藝限制導(dǎo)致Spark內(nèi)存容量不足的問題,本文利用容量密度更大的NVM來擴展Spark程序的可用內(nèi)存量.首先,本文利用NVM和DRAM性能接近的特點,直接將其用來擴展Java Heap的容量.同時,為了解決Spark自身計算行為導(dǎo)致的GC開銷,我們利用Unsafe接口開發(fā)了供Spark編程人員使用的可以直接將數(shù)據(jù)移出Java Heap并置于NVM的API,以便進(jìn)一步減輕GC開銷.
由于DRAM和NVM的性能具有一定的差距,因此需要將數(shù)據(jù)在二者之間恰當(dāng)布局才能避免程序性能的下降.數(shù)據(jù)隨機在DRAM和NVM之間分布時,和全部使用DRAM相比性能下降達(dá)32%.本文提出的異質(zhì)內(nèi)存編程框架,可以在Spark,OpenJDK兩個層次來進(jìn)行數(shù)據(jù)布局.在僅適用20%~25%的DRAM時,便可以達(dá)到全部使用DRAM時性能的90%以上.
首先,由于Spark框架運行于JVM之上,因此其內(nèi)存使用特點受到了JVM對Java Heap管理的影響,不同程序的訪存特點具有一定的共性.本文通過對多個Spark程序的分析,發(fā)現(xiàn)Java Heap中容量較小的新生代、元數(shù)據(jù)區(qū)的內(nèi)存讀寫比例遠(yuǎn)高于容量龐大的舊生代區(qū).因此,我們根據(jù)各個區(qū)域的訪存熱度將區(qū)域直接映射到了DRAM和NVM區(qū).
同時,Spark程序的訪存特點也受到了其自身計算行為的影響.Spark程序使用的數(shù)據(jù)(RDD),結(jié)構(gòu)規(guī)則,計算行為簡單,在構(gòu)造Spark應(yīng)用時,開發(fā)人員很容易感知發(fā)生在特定數(shù)據(jù)上的計算、訪存行為.因此,我們基于Off Heap機制開發(fā)了API來允許開發(fā)人員直接決定數(shù)據(jù)在DRAM和NVM中的位置.
此外,本文通過對Spark應(yīng)用訪存行為的分析,發(fā)現(xiàn)內(nèi)存中的大量數(shù)據(jù)訪問頻率低下.這些數(shù)據(jù)無法持續(xù)利用DRAM的性能,如“低延遲”和“超高帶寬(多通道)”.同時,這些數(shù)據(jù)的存活時間很長,每一次GC都會因為對這些數(shù)據(jù)的分析而造成顯著的開銷.因此,將這些大量的冷數(shù)據(jù)通過Off Heap置于NVM時,雖然會帶來一定的序列化開銷,但顯著地減少了GC開銷.而又比將數(shù)據(jù)置于磁盤帶來十分可觀的性能提升(可達(dá)88%).
最后,為了減少Spark程序開發(fā)人員的負(fù)擔(dān),數(shù)據(jù)在OpenJDK層次的映射將會自動完成;此外,我們在Spark層次提供了簡單的API接口,供開發(fā)人員根據(jù)Spark程序特點來布局?jǐn)?shù)據(jù).本文在第3節(jié)中對API使用規(guī)則進(jìn)行了描述,使其非常易于使用.
經(jīng)過實驗分析,本文提出的異質(zhì)內(nèi)存編程框架在搜索引擎離線分析(Spark PageRank[7])、圖計算(Spark GraphX)、社交網(wǎng)絡(luò)離線分析(Spark K-means[7])等領(lǐng)域中均取得了較好效果.
本文的主要貢獻(xiàn)如下:
1) 利用NVM高密度、接近DRAM性能的特點,將其用于服務(wù)器主存,在Java Heap,Off Heap兩個方面擴展了Spark編程框架的內(nèi)存容量.解決了由于DRAM容量無法滿足內(nèi)存計算需求增長所帶來的性能瓶頸.相較于DRAM不足時使用磁盤,使用NVM后應(yīng)用性能提升了88%.
2) 通過分析Spark程序的行為,實現(xiàn)了數(shù)據(jù)在異質(zhì)內(nèi)存上的合理布局.在僅用少量DRAM(20%~25%)和大量NVM的情況下,便可達(dá)到使用等量DRAM性能的90%左右.讓NVM可以實際應(yīng)用于內(nèi)存計算,使其“性能價格”比全部使用DRAM高了2.9倍.
3) 編程框架提供了簡單的API和自動布局策略,有很好的易用性,無需編程人員重新編寫已經(jīng)開發(fā)的應(yīng)用,僅需要簡單的Storage Level替換和相關(guān)功能開啟便可以將原有的Spark應(yīng)用運行于異質(zhì)內(nèi)存.
大數(shù)據(jù)是繼云計算、移動互聯(lián)網(wǎng)、物聯(lián)網(wǎng)之后的一個新興的前沿領(lǐng)域.MapReduce是一種流行的大數(shù)據(jù)編程框架,開發(fā)者只需要將數(shù)據(jù)用Map,Reduce函數(shù)串行處理,便可以利用高擴展性、容錯性的分布式計算框架來進(jìn)行高并發(fā)的處理.該框架目前廣泛應(yīng)用于主流大數(shù)據(jù)處理平臺,如Hadoop,Spark等.
以Spark為代表的內(nèi)存計算框架正在興起,并被企業(yè)廣泛采用.通過將大量的中間結(jié)果緩存于內(nèi)存,極大地減少了傳統(tǒng)Map,Reduce的計算過程中對磁盤的使用,尤其適用于加速迭代計算.然而,隨著數(shù)據(jù)量的快速增加,計算規(guī)模也逐漸增大,因此對內(nèi)存容量提出了迫切的需求.然而由于工藝水平的限制,目前主流的內(nèi)存介質(zhì),DRAM已經(jīng)很難滿足內(nèi)存計算需求的快速增長.當(dāng)內(nèi)存容量不足時,內(nèi)存計算性能將受到嚴(yán)重的干擾,限制了計算規(guī)模的增長.此外,DRAM功耗也隨著存儲密度的增加而逐漸增加,甚至可以占到某些服務(wù)器整機功耗的40%以上[8].
托管式語言(如Java,C#,Scala等)因具有跨平臺、面向?qū)ο?、垃圾回收機制(garbage collection, GC)等特性,被廣泛應(yīng)用于大數(shù)據(jù)系統(tǒng)開發(fā),如Spark[4],Hadoop[9]等均基于JVM(Java virtual machine)運行.托管式語言利用自己的堆(Java Heap)機制來管理從操作系統(tǒng)中獲取的內(nèi)存空間,因此運行于其上的應(yīng)用訪存特點均具有一些類似的特性.比如,其新生代的內(nèi)存寫比例明顯大于舊生代等.這種特點給研究人員提供了進(jìn)行數(shù)據(jù)快速布局的天然優(yōu)勢.
非易失性內(nèi)存(NVM)是一類具有非易失性的新型內(nèi)存介質(zhì).其不但具有和DRAM類似的性能,同時具有更高的存儲密度、更低的靜態(tài)功耗.但是,其也具有一些自身的缺點,相比于DRAM,其寫性能低下、寫壽命較低.因此,難以直接使用來全面替代DRAM.目前異質(zhì)內(nèi)存中,以PCM較為成熟,吸引了眾多研究者的探索.但利用DRAM和NVM構(gòu)成的異質(zhì)內(nèi)存卻可以滿足一些大數(shù)據(jù)計算應(yīng)用的需求.
由DRAM和NVM構(gòu)成的異質(zhì)內(nèi)存有2種主流結(jié)構(gòu):DRAM作為NVM緩存的豎直結(jié)構(gòu)(inclusive architecture);DRAM和NVM平級的結(jié)構(gòu)(exclusive architecture),如圖1所示.相比于前者,在大規(guī)模計算中,后者允許我們有更大的物理內(nèi)存可以使用,也減少了DRAM和NVM之間巨量的數(shù)據(jù)移動[8],因此本文工作基于平級結(jié)構(gòu).
Fig. 1 Architecture of heterogeneous memory[8]圖1 異質(zhì)內(nèi)存結(jié)構(gòu)[8]
本研究涉及了上層分布式編程框架、中層的托管式運行時系統(tǒng)、底層的非易失內(nèi)存3方面,所以本文將從這3個方面之間的聯(lián)系來對國內(nèi)外的研究工作進(jìn)行探討.
由于非易失性內(nèi)存(NVM)是一類內(nèi)存技術(shù)的統(tǒng)稱,其中包含了性能各異的介質(zhì)類型.目前針對NVM的研究,在應(yīng)用層次上可以分為兩大類:將NVM作為存儲介質(zhì);將NVM作為內(nèi)存介質(zhì).由于閃存技術(shù)已經(jīng)大規(guī)模的商用化,因此通過閃存來研究NVM在存儲層次的應(yīng)用較為成熟,清華大學(xué)總結(jié)了當(dāng)今NVM在存儲領(lǐng)域的應(yīng)用情況[10-11].而對于NVM在內(nèi)存層次的研究多以利用模擬器的方式進(jìn)行,中國科學(xué)院計算技術(shù)研究所對NVM應(yīng)用于內(nèi)存層次時的性能瓶頸進(jìn)行了透徹的分析[12].此外,還有針對NVM安全[13]、功耗[14]等方面的研究.本文將NVM應(yīng)用于內(nèi)存層次,將其和DRAM同時使用,構(gòu)建成大容量、低價格的異質(zhì)內(nèi)存.
對于由DRAM和NVM構(gòu)成的異質(zhì)內(nèi)存,如果不輔以恰當(dāng)?shù)臄?shù)據(jù)布局,會因為NVM的性能不足導(dǎo)致嚴(yán)重的性能瓶頸.因此,針對不同的應(yīng)用場景對異質(zhì)內(nèi)存進(jìn)行數(shù)據(jù)布局的管理工作是一個研究熱點.根據(jù)數(shù)據(jù)管理方式分類,常見的有硬件管理策略;硬件、操作系統(tǒng)結(jié)合的管理策略;運行時應(yīng)用程序員管理策略.本節(jié)按照該種分類形式,對國內(nèi)外現(xiàn)有的管理策略進(jìn)行介紹.
2.1.1 硬件管理策略
硬件管理策略多采用緩存結(jié)構(gòu),此時DRAM為NVM的緩存,通過類似于Cache的管理策略來將NVM中頻繁訪問的數(shù)據(jù)取到DRAM中,對上層操作系統(tǒng)、程序完全透明.其中,IBM研究院提出了由硬件管理的異質(zhì)內(nèi)存緩存結(jié)構(gòu),并提出了延遲寫、細(xì)粒度寫回等策略,在保證性能的前提下提高PCM的使用壽命[15].最終,該研究認(rèn)為只需使用NVM容量3%的DRAM,就可以使異質(zhì)內(nèi)存和同容量DRAM的性能接近.此外,匹茲堡大學(xué)[16]、密歇根大學(xué)[17]、賓夕法尼亞州立大學(xué)[18]、微軟研究院[19]等也提出了采用硬件來對異質(zhì)內(nèi)存進(jìn)行管理,以節(jié)省功耗、提升NVM壽命的管理策略.由硬件進(jìn)行冷熱數(shù)據(jù)識別、數(shù)據(jù)遷移開銷較小,但是硬件管理策略不適用于內(nèi)存容量巨大的大數(shù)據(jù)應(yīng)用,因為如果NVM容量太大,DRAM緩存的tag等標(biāo)志位會造成很大的浪費.如文獻(xiàn)[15]中所用配置,32 GB NVM,1 GB DRAM,16 way,256 B line時,便需要13% DRAM空間用作tag等標(biāo)志位,而本文的實驗規(guī)模在128 GB,面向的應(yīng)用環(huán)境在TB級別.此外,如果大數(shù)據(jù)程序的局部性不好,會導(dǎo)致數(shù)據(jù)頻繁的換入、換出DRAM,反而會造成更高的功耗,同時引起性能下降.
2.1.2 軟硬件結(jié)合管理策略
該種方式可以由硬件(內(nèi)存控制器)來完成冷熱數(shù)據(jù)的識別、數(shù)據(jù)遷移,然后由操作系統(tǒng)來進(jìn)行物理頁面和虛擬頁面的映射維護(hù)[20-21];或者由操作系統(tǒng)進(jìn)行在線的分析,識別出性能關(guān)鍵數(shù)據(jù),并在DRAM和NVM之間進(jìn)行數(shù)據(jù)遷移[22-24];亦或者由硬件、操作系統(tǒng)、上層應(yīng)用聯(lián)合完成數(shù)據(jù)識別、遷移等工作[8].該種管理方式可以應(yīng)用于緩存結(jié)構(gòu)和平級結(jié)構(gòu),較為靈活.如羅格斯大學(xué)提出了軟硬結(jié)合的Rapp(rank-based page placement)算法[20],其利用內(nèi)存控制器維護(hù)了一個多級隊列,每一級對應(yīng)訪問熱度不同的頁面,并根據(jù)此將熱頁面換入DRAM,冷頁面替換出到NVM.但是基于歷史使用信息的在線監(jiān)測,會造成一定比例的錯誤預(yù)測.同時,這種在線監(jiān)測也會帶來一定的開銷.中國科學(xué)院計算技術(shù)研究所通過對程序的具體分析發(fā)現(xiàn),數(shù)據(jù)可以根據(jù)產(chǎn)生位置被劃為為不同的類別,而且同一類別往往具有類似的訪存行為[8].并基于此提出了Rapp的改進(jìn)算法,即,首先根據(jù)靜態(tài)分析對數(shù)據(jù)進(jìn)行初步的分類,并直接布局到DRAM或NVM;然后在此基礎(chǔ)上應(yīng)用Rapp算法,可以有效減少數(shù)據(jù)遷移數(shù)量和監(jiān)測開銷.類似的數(shù)據(jù)分類研究還有文獻(xiàn)[25-26].硬件與操作系統(tǒng)結(jié)合的管理方式多是以page為粒度,并使用基于歷史訪問信息的在線監(jiān)測方式.但是對于不同類型的程序,固定的page粒度往往不是最優(yōu)的選擇,如文獻(xiàn)[27]通過研究發(fā)現(xiàn)在某些應(yīng)用中(jpeg encoding),以object粒度進(jìn)行數(shù)據(jù)遷移可以比page粒度進(jìn)行數(shù)據(jù)遷移獲得更好的功耗收益.然而,對內(nèi)存使用量巨大的大數(shù)據(jù)應(yīng)用來說,page卻顯得過于細(xì)粒度,并且會造成較大的監(jiān)測開銷.而且,由于大數(shù)據(jù)系統(tǒng)中運行時堆的存在,其自身便會對數(shù)據(jù)進(jìn)行移動,往往會破壞操作系統(tǒng)優(yōu)化好的數(shù)據(jù)布局.
2.1.3 運行時應(yīng)用程序員管理策略
程序的計算行為、數(shù)據(jù)的結(jié)構(gòu)特點往往決定了數(shù)據(jù)被訪問的特點.Intel研究院、佐治亞理工學(xué)院通過對大數(shù)據(jù)程序進(jìn)行分析,根據(jù)數(shù)據(jù)訪問的形式,將其分為順序訪問、指針類型數(shù)據(jù)訪問、隨機訪問3類,而且發(fā)現(xiàn)每一類數(shù)據(jù)的訪問開銷也各不相同.如對于同樣數(shù)量的讀寫,指針類型數(shù)據(jù)的訪問延遲開銷遠(yuǎn)大于被順序訪問的數(shù)據(jù).因此該研究提出了結(jié)合靜態(tài)分析來調(diào)整數(shù)據(jù)在異質(zhì)內(nèi)存中布局的方式[3].但是該研究提供的數(shù)據(jù)布局操作只能作用于C,C++實現(xiàn)的大數(shù)據(jù)系統(tǒng),并沒有能力控制基于托管式語言實現(xiàn)的大數(shù)據(jù)平臺中的數(shù)據(jù).而流行的大數(shù)據(jù)系統(tǒng)Hadoop,Spark等,往往是基于托管式語言實現(xiàn)的.類似地,文獻(xiàn)[28]也提出了通過編譯靜態(tài)分析的方式來識別數(shù)據(jù)上的訪問頻度,并指導(dǎo)數(shù)據(jù)在NUMA節(jié)點上進(jìn)行遷移.相對于操作系統(tǒng),硬件往往以page為數(shù)據(jù)的遷移粒度,編譯器、程序員往往可以做到更加靈活的數(shù)據(jù)管理粒度,如文獻(xiàn)[27]提出了編譯分析和操作系統(tǒng)相結(jié)合的方式,在object級別進(jìn)行細(xì)粒度冷熱數(shù)據(jù)分析、遷移.不過,應(yīng)用直接管理NVM上的數(shù)據(jù)往往需要操作系統(tǒng)給予一定的支持,對此佐治亞理工學(xué)院提出了一套允許處理器可以直接訪問NVM的系統(tǒng)PMFS[29].但是,數(shù)據(jù)的訪問特點往往是隨著程序執(zhí)行而不斷變化的[30],因此需要配合運行時的監(jiān)測來對數(shù)據(jù)布局進(jìn)行動態(tài)的調(diào)整才取得更大的收益.同時,編譯分析往往需要對應(yīng)用進(jìn)行離線分析(off-line profiling),而當(dāng)程序的輸入集改變時程序行為可能進(jìn)行相應(yīng)的變化,導(dǎo)致離線分析的準(zhǔn)確性會有所降低.
本文面向的應(yīng)用環(huán)境內(nèi)存規(guī)模單節(jié)點便在上百GB,甚至討論了TB級別.因此,上述的細(xì)粒度軟件、硬件策略并不能很好地契合本文研究對象的需求.此外,由于本文所面向的內(nèi)存計算框架Spark運行于OpenJDK之上,上述的硬件、操作系統(tǒng)、編程接口等數(shù)據(jù)管理策略并沒有考慮到托管式運行時對數(shù)據(jù)的移動,所以很可能造成數(shù)據(jù)的無效遷移.
本文的應(yīng)用環(huán)境為分布式內(nèi)存計算框架.因此,我們研究了當(dāng)今一些針對大數(shù)據(jù)系統(tǒng)進(jìn)行優(yōu)化的主流工作作為參考.這些優(yōu)化工作給本文的性能調(diào)優(yōu)提供了很好的啟發(fā).
隨著上層軟件系統(tǒng)的發(fā)展,越來越復(fù)雜的軟件層次導(dǎo)致了程序執(zhí)行特點、語義信息的多樣性與復(fù)雜化.而上層程序的語義在下傳過程中的逐漸丟失,導(dǎo)致運行時和上層軟件系統(tǒng)之間出現(xiàn)了多個層次的不匹配行為.如垃圾回收機制中“生代假設(shè)”和大數(shù)據(jù)系統(tǒng)數(shù)據(jù)使用行為的不匹配[5];運行時處理數(shù)據(jù)的粒度(object)和大數(shù)據(jù)系統(tǒng)數(shù)據(jù)的使用粒度(如Spark中的RDD)不匹配.這些不匹配造成GC策略效率低下,成為了內(nèi)存計算框架的性能瓶頸,甚至可以造成50%以上的開銷.為了解決運行時和和大數(shù)據(jù)系統(tǒng)的不匹配行為,國內(nèi)外學(xué)者從2個方面進(jìn)行了研究:1)從運行時出發(fā),修改運行時機制匹配大數(shù)據(jù)系統(tǒng)的數(shù)據(jù)使用行為;2)從大數(shù)據(jù)系統(tǒng)出發(fā),修改其數(shù)據(jù)使用行為,以便符合運行時的管理特點.
2.2.1 面向大數(shù)據(jù)系統(tǒng)調(diào)整運行時的工作
University of California,Irvine的研究者通過對Hyracks,Hadoop,GraphChi大數(shù)據(jù)系統(tǒng)的研究,發(fā)現(xiàn)了適用于大數(shù)據(jù)系統(tǒng)的數(shù)據(jù)生命周期假設(shè)——“epoch假設(shè)”,并在HotSpot基礎(chǔ)上提出了新的GC機制——Yak[5].其研究發(fā)現(xiàn),大數(shù)據(jù)計算行為會導(dǎo)致數(shù)據(jù)生命周期具有epoch(世代)的特點.大多數(shù)的數(shù)據(jù)在epoch開始時產(chǎn)生,其生命周期一直持續(xù)到對應(yīng)的epoch結(jié)束.而當(dāng)前運行時的GC策略使用的數(shù)據(jù)生命周期假設(shè)大多數(shù)數(shù)據(jù)對象的生命周期都是短暫的,因此可以通過頻繁的輕量級GC(minor GC)來對多數(shù)無用數(shù)據(jù)進(jìn)行回收,并將少量的存活時間較長的數(shù)據(jù)遷移到舊生代,等待全局GC(full GC)處理[31-32].而一些大數(shù)據(jù)系統(tǒng)的數(shù)據(jù)生命周期不再遵循這種假設(shè),因此其觸發(fā)的minor GC行為多數(shù)是無效的,只能回收極少量數(shù)據(jù),同時帶來巨大的分析開銷.因此,文獻(xiàn)[5]針對這些大數(shù)據(jù)系統(tǒng)提出了新的數(shù)據(jù)使用假設(shè)——epoch假設(shè),并利用該假設(shè)在運行時堆中劃分出一個新的區(qū)域進(jìn)行管理.但是,經(jīng)過我們的分析,epoch假設(shè)不適用于Spark等內(nèi)存計算系統(tǒng).Spark PageRank執(zhí)行的過程中,每一次GC均會回收較多的無用數(shù)據(jù).因此該研究的適用范圍具有一定的局限性.
2.2.2 調(diào)整大數(shù)據(jù)系統(tǒng)來重新匹配運行時特點
傳統(tǒng)的GC分析策略無法應(yīng)對大數(shù)據(jù)系統(tǒng)產(chǎn)生的大量數(shù)據(jù)對象[33].GC需要分析眾多的數(shù)據(jù)引用,而這些分析導(dǎo)致GC消耗的時間甚至占據(jù)了整個程序運行時間的50%以上[5-6].而研究者發(fā)現(xiàn),大數(shù)據(jù)系統(tǒng)中產(chǎn)生的數(shù)據(jù)對象生命周期較為規(guī)律,所以提出了Off Heap的思想.即將大量的、生命周期規(guī)律的數(shù)據(jù)移出Java Heap,置于本地內(nèi)存(native memory),由程序員或者編譯器來進(jìn)行釋放,不再由GC進(jìn)行分析.Databrick和University of California,Irvine的研究者分別提出了自己的Off Heap框架,見文獻(xiàn)[6,34].其中文獻(xiàn)[6]使用編譯器對代碼進(jìn)行分析和變換,并使用region-based內(nèi)存管理思想[35-37]來進(jìn)行數(shù)據(jù)管理.文獻(xiàn)[34]對程序員提供了Off Heap接口,可以讓開發(fā)人員根據(jù)需求將對應(yīng)的數(shù)據(jù)分配到Off Heap.經(jīng)過我們分析,通過編譯變換的手段,僅能支持較少的大數(shù)據(jù)系統(tǒng),如無法對scala語言實現(xiàn)的Spark系統(tǒng)進(jìn)行變化.同時,將數(shù)據(jù)的創(chuàng)建、銷毀任務(wù)重新返回給程序員,不但增加了編程難度,同時減弱了復(fù)雜系統(tǒng)的穩(wěn)定性.
華中科技大學(xué)和Databricks面向Spark計算框架,分別提出了將常規(guī)Java數(shù)據(jù)對象壓縮為字節(jié)流,并直接在字節(jié)流上進(jìn)行計算的思路[34,38].通過這種數(shù)據(jù)類型的轉(zhuǎn)化,不但減少了數(shù)據(jù)所占用的空間大小,還極大地減少了數(shù)據(jù)對象的數(shù)目,因此減少了GC帶來的開銷.但是,將常規(guī)Java數(shù)據(jù)對象轉(zhuǎn)化為字節(jié)流,并直接在其上進(jìn)行計算的操作,該方式對Java數(shù)據(jù)對象的結(jié)構(gòu)有一定限制,限制了大數(shù)據(jù)系統(tǒng)的適用范圍.同時,這種計算雖然節(jié)省了GC開銷,但要比直接在Java數(shù)據(jù)對象上帶來更大的計算開銷,因此當(dāng)需要GC的數(shù)據(jù)較少時,這種框架并不一定能取得優(yōu)勢.
通過對該部分研究工作的調(diào)研,讓我們了解了內(nèi)存計算系統(tǒng)的性能瓶頸,怎樣平衡序列化的CPU計算開銷和GC的開銷、Off Heap機制的利用等問題.
托管式語言,如scala,Java,C#等,因為其易編程性和良好的擴展性被廣泛地應(yīng)用于嵌入式開發(fā)、分布式系統(tǒng)開發(fā).托管式語言會自動控制數(shù)據(jù)在堆中的位置.另外其所具有的垃圾回收機制(GC)會在程序運行過程中動態(tài)地回收程序無用的數(shù)據(jù),并在Object Promotion,Compact等過程中以object粒度移動堆中的數(shù)據(jù).這給通過運行時對異質(zhì)內(nèi)存中的數(shù)據(jù)進(jìn)行管理提供了機會.如澳大利亞國立大學(xué)提出了一套硬件、操作系統(tǒng)、運行時結(jié)合的NVM管理方式來延長NVM的使用壽命.當(dāng)硬件監(jiān)測到NVM局部損壞時,相比起直接舍棄掉整個page(4KB),運行時會避免使用對應(yīng)的line(256B).在該種策略下,即使NVM的損壞率達(dá)到50%時,僅會引起12%的性能下降[39].筑波大學(xué)[40-43]提出可以將運行時堆中的新生代直接映射到DRAM,但是并沒有給出具體的定量分析來進(jìn)行解釋.文獻(xiàn)[44]對Java Heap各個區(qū)域的訪存冷熱進(jìn)行了分析,并提出了在函數(shù)粒度對冷熱數(shù)據(jù)進(jìn)行識別,并在Object級別遷移的想法.但其面向的應(yīng)用為單機應(yīng)用程序.此外文獻(xiàn)[45-46]等工作提出了如何在執(zhí)行GC時避免發(fā)成swap數(shù)據(jù)到硬盤現(xiàn)象,當(dāng)異質(zhì)內(nèi)存為緩存結(jié)構(gòu)時,可以借鑒這些研究的成果.
該部分工作均為基于傳統(tǒng)的單機Java程序進(jìn)行.對于TB級別的分布式內(nèi)存計算系統(tǒng),其計算、訪存行為將會發(fā)生很大的改變.本文重新對TB級別的大規(guī)模內(nèi)存計算系統(tǒng)進(jìn)行了分析,并提出了高效、可行的數(shù)據(jù)布局策略.
Spark和OpenJDK均有自己的內(nèi)存管理模型,數(shù)據(jù)的布局同時受到二者的內(nèi)存管理特點影響.因此,為了使數(shù)據(jù)可以在異質(zhì)內(nèi)存中合理地布局,我們在Spark和OpenJDK兩個層次進(jìn)行了異質(zhì)內(nèi)存支持.在Spark層次提供了開發(fā)人員可以主動調(diào)用的數(shù)據(jù)布局API;在OpenJDK層次我們根據(jù)HotSpot的Java Heap管理特點提供了冷、熱數(shù)據(jù)的自動布局方案.二者的對應(yīng)關(guān)系如圖2所示.
Fig. 2 Architecture of heterogeneous memory programming framework based on Spark圖2 基于Spark的異質(zhì)內(nèi)存編程框架結(jié)構(gòu)
本節(jié)以Spark層的內(nèi)存管理模型為切入,對提出的異質(zhì)內(nèi)存編程框架的設(shè)計與實現(xiàn)進(jìn)行闡述:
Spark將內(nèi)存劃分為Storage Memory,Execu-tion Memory兩大部分.Storage Memory中為緩存的RDD數(shù)據(jù);而Execution Memory中為Map,Shuffle等計算數(shù)據(jù).
對于Storage Memory中的數(shù)據(jù),其由存活時間較長、數(shù)量巨大的Object群構(gòu)成,因此會給GC的掃描過程帶來顯著的開銷.同時,Storage Memory中的眾多緩存數(shù)據(jù)主要用于容錯,其訪問并不頻繁,因此可以將其中的大量冷數(shù)據(jù)序列化、壓縮后,通過Off Heap機制置于NVM.由于RDD數(shù)據(jù)的冷熱可以較容易地由Spark應(yīng)用開發(fā)人員識別,因此我們提供API來供其控制數(shù)據(jù)布局.
對于Execution Memory中的數(shù)據(jù),其只能存在于Java Heap中.因此,為了解決DRAM無法滿足內(nèi)存計算規(guī)模增長而造成的Java Heap相對于計算數(shù)據(jù)量較小時頻繁GC帶來的開銷,我們利用存儲密度遠(yuǎn)大于DRAM的NVM來擴展Java Heap.但是,由于該部分?jǐn)?shù)據(jù)訪問頻繁,對內(nèi)存性能(帶寬、延遲)有較高要求.因此,我們進(jìn)一步利用OpenJDK對其中的冷、熱數(shù)據(jù)進(jìn)行了自動布局.
為了減少 Spark 應(yīng)用開發(fā)人員的復(fù)雜性,我們僅僅暴露出了一個簡單的Storage Level接口.一旦開發(fā)人員使用了我們的接口來指導(dǎo)Storage Memory中數(shù)據(jù)的布局,OpenJDK便自動對Java Heap中數(shù)據(jù)的布局進(jìn)行自動管理.即使用戶不使用我們提供的Storage level接口,也可以通過命令快速開啟OpenJDK層次的數(shù)據(jù)自動布局.
Storage Memory用于儲存被persist,cache的RDD數(shù)據(jù),這些數(shù)據(jù)為一些中間數(shù)據(jù),或者用于容錯,其中眾多的數(shù)據(jù)訪問并不頻繁.為了降低GC開銷,Spark Tungsten利用OpenJDK的unsafe接口,開發(fā)了Spark Off Heap機制.Spark和OpenJDK的內(nèi)存管理對應(yīng)關(guān)系如表1所示:
Table1TheRelationbetweenSparkandOpenJDKMemoryManagement
表1 Spark和OpenJDK內(nèi)存管理模型之間的對應(yīng)關(guān)系
Storage Memory中的數(shù)據(jù)可以通過Off Heap機制,由Spark應(yīng)用開發(fā)人員細(xì)粒度地決定其在異質(zhì)內(nèi)存中的位置;我們增加了一個Storage Level來讓Spark應(yīng)用開發(fā)人員直接將持久化的RDD置于NVM:NVM_OFF_HEAP;同時,我們將原有的OFF_HEAP重命名為DRAM_OFF_HEAP.此時RDD所具有的Storage Level如表2所示:
Table 2 RDD Storage Level表2 RDD存儲等級
Note: Only list partial RDD storage levels which affect RDD’s position and status.
Spark程序開發(fā)人員只需要將原有程序中的DISK_ONLY,MEMORY_AND_DISK,MEMORY_AND_DISK_SER等攜帶“DISK”,“SER”關(guān)鍵字的Storage Level直接替換為本文提供的NVM_OFF_HEAP,此時便將冷數(shù)據(jù)置于了NVM Off Heap中.而對于一些只能處于非序列化狀態(tài)的頻繁訪問的熱數(shù)據(jù),仍舊將其保留在Java Heap中,交由OpenJDK來控制其在異質(zhì)內(nèi)存中的布局,如圖3所示.該API十分易用使用,并未給開發(fā)人員增加額外額性能分析負(fù)擔(dān).
Fig. 3 An example of API: NVM_OFF_HEAP’s usage圖3 NVM_OFF_HEAP 接口用法展示
而對于有經(jīng)驗的開發(fā)者,仍舊可以根據(jù)自己的經(jīng)驗,將持久化的RDD置于Off Heap的DRAM區(qū)域,或者序列化后直接置于Java Heap中.該框架在提供易用性的同時,并未減少Spark對于RDD控制的靈活度.
Execution Memory用于存儲進(jìn)行map,shuffle等操作的計算時的數(shù)據(jù),其上會頻繁地發(fā)生計算、訪存行為.Execution Memory中的數(shù)據(jù)和Storage Memory中非序列化的RDD只能置于Java Heap中,而數(shù)據(jù)在Java Heap中的布局均由OpenJDK控制,應(yīng)用程序無法直接進(jìn)行布局.因此,我們需要在OpenJDK層次進(jìn)行修改,來控制應(yīng)用數(shù)據(jù)在異質(zhì)內(nèi)存中的布局.
不同于磁盤,NVM具有良好的隨機讀寫性能,不但可以利用Off Heap機制來儲存序列化的RDD,也可用來擴展Java Heap,減少頻繁GC帶來的開銷.Java Heap中的數(shù)據(jù)需要頻繁的訪問,但NVM相較于DRAM性能較弱,因此需要將Java Heap中的數(shù)據(jù)在異質(zhì)內(nèi)存中進(jìn)行合理布局,否則性能會顯著下降.本文使用了文獻(xiàn)[44]的部分研究成果.該研究針對的是單機常規(guī)Java應(yīng)用,但是經(jīng)過我們分析,Spark這類分布式內(nèi)存計算應(yīng)用同樣具有類似的性質(zhì).
OpenJDK使用自己的內(nèi)存模型來管理從操作系統(tǒng)中獲取的空間.目前其采用的HotSpot機制,將內(nèi)存劃分為新生代、舊生代、元數(shù)據(jù)區(qū)三大部分.新生代又細(xì)分為edenfromto三個區(qū)域.按照文獻(xiàn)[44]中的分析方法,我們發(fā)現(xiàn)新生代仍然占據(jù)了大部分的cache miss,并伴有大量的內(nèi)存寫操作.不同于文獻(xiàn)[44]中的結(jié)論,此時的cache已經(jīng)無法處理內(nèi)存計算應(yīng)用中較大的元數(shù)據(jù)區(qū),其會頻繁地造成cache miss.所以,本文將新生代、元數(shù)據(jù)區(qū)直接定位到DRAM.而龐大的舊生代會隨機使用余下的其他區(qū)域.
一旦Spark程序開發(fā)人員使用本文提供的Storage Level來將部分持久化的RDD布局到NVM區(qū)域,OpenJDK便會自動布局新生代、元數(shù)據(jù)區(qū)到DRAM區(qū)域.而其他部分將會自由使用剩余的DRAM和NVM.或者不用NVM_OFF_HEAP接口時,可以由單一的命令:-XyoungGenDRAM,開啟OpenJDK的自動映射功能.為了確保新生代可以完全至于DRAM區(qū),框架在盡可能少影響性能的前提下,限制了新生代、舊生代的容量.此時雖然可能造成更多的Minor GC,但是卻極大地減少了在NVM上的訪存數(shù)量.同時,該方案可以減少對DRAM的需求,緩解了由于DRAM容量不足而造成的內(nèi)存計算規(guī)模限制.
本文在Spark,OpenJDK兩個層次,分別提供了手動調(diào)用的API和Java Heap中數(shù)據(jù)的自動映射2種相互配合的方式,來將數(shù)據(jù)布局到異質(zhì)內(nèi)存.僅向Spark程序開發(fā)人員暴露簡單的編程接口,便可將Spark Storage Memory,Spark Execution Memory中的數(shù)據(jù)合理地布局到DRAM和NVM.通過使用NVM來減少內(nèi)存計算系統(tǒng)對DRAM容量的需求,解決了由于DRAM工藝瓶頸對內(nèi)存計算規(guī)模持續(xù)擴展的限制.Spark編程框架中的數(shù)據(jù)布局形式如圖2所示.本文對Big Data Bench中提供的搜索引擎離線分析(PageRank)、圖計算(GraphX)、社交網(wǎng)絡(luò)分析(K-means)等程序進(jìn)行了性能分析,并取得了較好的結(jié)果.
本節(jié)針對Big Date Bench中的PageRank[7]應(yīng)用,分別在磁盤IO、GC開銷、Spark訪存特點等方面進(jìn)行了實驗分析,剖析了內(nèi)存不足時造成Spark性能瓶頸的具體原因.結(jié)合Spark程序的性能瓶頸,本節(jié)解釋了編程框架的設(shè)計原則,并展示了如何通過使用該編程框架在異質(zhì)內(nèi)存中取得良好的性能.
經(jīng)過分析發(fā)現(xiàn),當(dāng)物理內(nèi)存容量不足時,Spark仍舊會產(chǎn)生大量的磁盤操作,造成較高比例的IO開銷;同時由于Java Heap空間不足,大規(guī)模的計算將會造成頻繁的GC,嚴(yán)重地降低了性能;此外,由于Spark程序會緩存眾多的中間結(jié)果到Java Heap來加速計算、用于容錯,這也給GC帶來了顯著的開銷.同時,在使用NVM時,需要合理布局?jǐn)?shù)據(jù),否則會因為NVM性能不如DRAM,造成嚴(yán)重的性能下降.4.4節(jié)闡述了如何利用本文提出的編程框架解決以上問題.通過使用本文提出的異質(zhì)內(nèi)存編程框架,可以在僅使用20%~25%DRAM的情況下,達(dá)到使用等量DRAM性能的90%以上,并比DRAM不足,使用磁盤時加速88%.
本節(jié)首先討論了內(nèi)存容量不足時帶來的磁盤IO開銷和GC開銷的問題.在分析其原因的同時,展示了充足內(nèi)存如何帶來可觀的加速比.隨后展示了如何通異質(zhì)內(nèi)存編程框架,利用性能較差的NVM來達(dá)到接近充足DRAM時的性能.并討論了該Spark編程框架在更大計算規(guī)模上的擴展性.最后討論了由于異質(zhì)內(nèi)存編程框架使用了序列化而帶來的額外CPU計算開銷問題.
1) NVM模擬
本文利用NUMA平臺來模擬DRAM和NVM構(gòu)成的平級異質(zhì)內(nèi)存架構(gòu)[44].將計算固定到CPU0,此時Node0上的本地內(nèi)存為DRAM,Node1上的遠(yuǎn)端內(nèi)存為NVM.CPU0訪問Node1上內(nèi)存的延遲為訪問本地內(nèi)存的2.5倍,帶寬約為本地內(nèi)存的13,符合PCM和DRAM的參數(shù),具體詳見表3.此外,還可以利用文獻(xiàn)[44]中使用的干擾程序來進(jìn)一步降低延遲和帶寬.相較于傳統(tǒng)的Trace模擬器,該種方式支持運行大規(guī)模的分布式程序.
Table 3 Comparison of DRAM and NVM Technology [3]表3 DRAM 和 NVM 參數(shù)對比[3]
2) 硬件和Spark的配置
Spark Master:
CPU X5650, 2.67 GHz, x2;
Memory 雙通道,DDR3, 1 333 MHz.
Spark Slave:
CPU E7-4809 v3, 2.00 GHz, x4;
Memory雙通道,DDR 4, 1 867 MHz.
3) 測試用例
本文使用Big Data Bench[7]作為測試用例.本節(jié)選用其中的Spark PageRank來進(jìn)行性能解析.第5節(jié)將選用其他類型應(yīng)用進(jìn)行性能測試.為了避免Spark配置、RDD不同狀態(tài)帶來的不公平現(xiàn)象.本文將Spark PageRank調(diào)整到性能最優(yōu)狀態(tài),調(diào)整前后的性能對比見表4所示.頻繁訪問的RDD以非序列化的形式置于DRAM中(MEMORY_ONLY),而訪問較少、用于容錯的RDD將被設(shè)置為MEMORY_AND_DISK_SER,來避免巨大的GC開銷.經(jīng)過測試,在本文的大內(nèi)存環(huán)境中,該配置性能處于性能最佳狀態(tài).在后面的測試中,如無特殊標(biāo)注,均使用該調(diào)優(yōu)后的測試用例.
Table 4 Optimize Spark PageRank’s Performance表4 優(yōu)化Spark PageRank性能
由于磁盤性能和內(nèi)存、處理器的巨大差距,其常常成為整個系統(tǒng)的性能瓶頸.因此,從硬件、操作系統(tǒng)、編程框架多個層次探索如何消除磁盤開銷是研究熱點.而內(nèi)存計算系統(tǒng),即在編程框架層次,通過將中間計算結(jié)果緩存到內(nèi)存中,減少對磁盤的使用.同時,當(dāng)服務(wù)器內(nèi)存充足時,操作系統(tǒng)、文件系統(tǒng)也會利用空閑內(nèi)存緩存磁盤內(nèi)容,以減少磁盤IO操作.
由于DRAM的工藝水平限制,其密度難以持續(xù)增加.因此,DRAM容量便逐漸成為了內(nèi)存計算規(guī)模擴展的瓶頸.
本節(jié)用一個較小規(guī)模的應(yīng)用(memory footprint在100 GB左右)運行在32 GB物理內(nèi)存上,來展示物理內(nèi)存不足時造成的問題.此時為了避免應(yīng)用程序造成swap引起系統(tǒng)性能嚴(yán)重下降,本節(jié)將Spark Worker使用的內(nèi)存限制在30 GB.當(dāng)內(nèi)存容量和計算規(guī)模同時擴大時,只要服務(wù)器的內(nèi)存容量無法滿足內(nèi)存計算的需求,從而造成對磁盤的訪問時,該問題仍舊存在.同時,本文用128 GB DRAM來表示DRAM無限大,可以滿足計算所需內(nèi)存的完美情況.表5中的第1、第2列展示了Spark相同配置下,只需給予充足物理內(nèi)存,便可減少磁盤開銷達(dá)49%.物理內(nèi)存不足時,造成性能嚴(yán)重下降的原因有2個方面:
1) 物理內(nèi)存容量限制了Java Heap大小,本應(yīng)寫入內(nèi)存的持久化RDD,因內(nèi)存而不足而寫入磁盤;
2) 操作系統(tǒng)無足夠可用物理內(nèi)存來進(jìn)行磁盤緩存操作,導(dǎo)致大量數(shù)據(jù)直接寫入磁盤,隨后從磁盤讀取所需數(shù)據(jù).
Table 5 Spark PageRank’s Performance Comparison of Before and After Utilizing Heterogeneous Memory Programming Framework表5 利用異質(zhì)內(nèi)存編程框架后Spark PageRank的性能對比
Fig. 4 Trend of disk read request number and CPU IO wait time圖4 磁盤讀請求數(shù)量、CPU IO等待時間的變化趨勢
如表5中第1、第2列所示,當(dāng)Spark Executor(Java Heap)容量不足時,有額外的26GB數(shù)據(jù)寫入磁盤.這些數(shù)據(jù)需要在隨后被讀取來用于計算.此外,由于此時沒有充足的空閑物理內(nèi)存用于緩存磁盤數(shù)據(jù),因此,大量RDD會直寫入磁盤,并在隨后計算時立即讀取,造成了頻繁的CPU IO等待.圖4中列出了物理內(nèi)存不足時,磁盤IO read request數(shù)目以及IO wait時間隨程序運行的變化趨勢.從圖4中可以看到,CPU IO wait時間基本和磁盤的read request趨勢相符,頻繁的磁盤read request造成了較嚴(yán)重的CPU IO wait.
在完全同樣配置、充足物理內(nèi)存的情況下再次運行程序,其性能如表5第2列所示.從運行時間可以看到,通過增大物理內(nèi)存,雖然沒有減少持久化RDD寫入磁盤的操作,但是通過充足的內(nèi)存作為磁盤緩存,可以明顯地消除磁盤讀、寫帶來的影響.經(jīng)過測試,此時磁盤讀取請求數(shù)量很少.
不過,由于目前針對磁盤的優(yōu)化工作很多,磁盤作為性能瓶頸的情況正在逐漸減少.文獻(xiàn)[47]通過分析一些大數(shù)據(jù)框架得出,磁盤對大數(shù)據(jù)系統(tǒng)造成的性能瓶頸一般在19%左右.
本節(jié)通過對比相同Spark配置下充足物理內(nèi)存帶來的性能提升,分析了DRAM不足時造成Spark程序性能瓶頸的原因.由于NVM的密度為DRAM的10倍左右(表3),因此,其在解決內(nèi)存計算規(guī)模擴展性方面具有良好的潛力.本文在4.3~4.5節(jié)分析了如何利用高密度的NVM帶來可觀的加速比.
本節(jié)分析內(nèi)存容量不足時造成GC開銷過大的原因,以及如何利用大內(nèi)存恰當(dāng)?shù)南鼼C開銷.
內(nèi)存計算系統(tǒng)中,GC開銷主要由2部分組成:
1) DRAM容量無法滿足內(nèi)存計算規(guī)模,限制了Java Heap大小,造成頻繁的GC.
2)大量長期存活的數(shù)據(jù)被緩存到Java Heap,每次GC均需要掃描眾多的數(shù)據(jù).
由于數(shù)據(jù)的快速增長,內(nèi)存計算對內(nèi)存容量的需求也快速增長,而DRAM已經(jīng)難以滿足該需求.因此,相對于處理的數(shù)據(jù),內(nèi)存的容量不足會導(dǎo)致Java Heap頻繁的GC.
每一次GC都需要分析當(dāng)前Java Heap中存活的Object,并將其移動到舊生代.而由于大數(shù)據(jù)應(yīng)用使用的內(nèi)存容量十分巨大,存活的object數(shù)目眾多,因此每一次GC都會造成嚴(yán)重的開銷.在我們的實驗中,當(dāng)Java Heap達(dá)到120GB時,單次Full GC的開銷甚至可以達(dá)到128s.此外,由于Spark會將大量的RDD數(shù)據(jù)緩存于內(nèi)存中,這些數(shù)據(jù)長期存活,給每一次GC都帶來了額外的分析、移動開銷.所以,在很多大數(shù)據(jù)應(yīng)用中,GC開銷甚至可以占到程序運行時間的50%[5-6].
因此,降低GC開銷是內(nèi)存計算的一個研究熱點.該部分工作可以劃分為2類:修改GC策略來匹配大數(shù)據(jù)系統(tǒng)數(shù)據(jù)特點;修改內(nèi)存計算框架來適應(yīng)GC策略.例如,文獻(xiàn)[5]認(rèn)為大量的數(shù)據(jù)存活于一次迭代計算中,在計算結(jié)束時同時被回收.在結(jié)束前的GC行為是無效的,只會造成額外的開銷.因此其根據(jù)大數(shù)據(jù)的計算行為,重新調(diào)整了GC的發(fā)生位置來降低GC頻率.
經(jīng)過我們分析,Spark Execution Memory部分基本遵循文獻(xiàn)[5]提出的假設(shè).此時,只需直接擴大Java Heap便可以有效地減少GC的頻率,也便因此減少了無效GC的發(fā)生.然而,Spark Storage Memory并不遵循生代假設(shè).以Spark PageRank為例,大量持久化的RDD將會存活很長時間,對該部分內(nèi)容的GC,將會造成大量的無用開銷.
Spark Tungsten基于sun.misc.Unsafe接口提出了將部分Storage Memory中的數(shù)據(jù)移出Java Heap的機制.即將性能不關(guān)鍵的持久化RDD置于Off Heap,避免GC對其的掃描開銷.本文基于Off Heap開發(fā)的面向異質(zhì)內(nèi)存的編程框架,也是考慮到利用NVM和DRAM接近的性能,將訪問不頻繁的并且長期存活的RDD直接至于NVM Off Heap,來降低GC開銷.
表5中第3列展示了充足的物理內(nèi)存,并設(shè)置大Java Heap時,通過降低GC頻度帶來的性能提升.相比于Java Heap較小的第2列數(shù)據(jù),加速比達(dá)到了38%.圖5為展示了將第3列(大內(nèi)存、大Java Heap)消除的時間分散到磁盤IO開銷、GC開銷后的比例.將表5中第1列數(shù)據(jù)作為基準(zhǔn),第2列數(shù)據(jù)作為通過超大物理內(nèi)存消除磁盤IO開銷的結(jié)果,將第3列作為同時消除磁盤和GC開銷的結(jié)果.由此可以看到充足物理內(nèi)存、大Java Heap帶來的明顯加速比.
Fig. 5 Decomposition of performance improvement causedby enough physical memory and big Java Heap圖5 充足內(nèi)存帶來性能提升的分解
通過4.2節(jié)、4.3節(jié)的分析可以看到內(nèi)存不足時對Spark程序性能造成了嚴(yán)重的影響.本節(jié)以Spark中的內(nèi)存管理模型:Storage Memory,Execution Memory兩個方面為切入口來闡述本文提出的異質(zhì)內(nèi)存編程框架如何利用NVM從Java Heap,Off Heap兩個方面來擴展容量,降低GC開銷、磁盤IO開銷.
4.4.1 針對Spark Storage Memory的管理
Spark Storage Memory不但會因為內(nèi)存容量不足導(dǎo)致巨大的磁盤操作,即使內(nèi)存充足時,其中大量的數(shù)據(jù)長期存活于Java Heap,仍舊會造成顯著地GC開銷.除此之外,當(dāng)Storage Memory沒有空間來存儲新的持久化RDD時,Spark會將舊的RDD序列化后寫入磁盤,這無疑會增加很大比例的CPU額外計算開銷.因此,本節(jié)討論如何利用NVM來消除DRAM容量不足時造成的磁盤IO開銷、GC開銷,以及Spark數(shù)據(jù)使用特點造成的GC開銷.
HotSpot中的Parallel GC需要掃描整個Java Heap中的存活數(shù)據(jù).而Storage Memory中的眾多用于加速計算、容錯恢復(fù)的數(shù)據(jù)會長期在內(nèi)存中存活.因此,GC對其中的數(shù)據(jù)掃描將會造成無謂的開銷.在大規(guī)模的內(nèi)存計算中,Storage Memory默認(rèn)會占據(jù)整個Java Heap 50%的空間.然而和Execution Memory受限于Java Heap大小不同,持久化的RDD將會隨著程序的執(zhí)行而逐漸增加,直至將無法置于Java Heap的數(shù)據(jù)序列化后寫入到磁盤.雖然可以通過將中間數(shù)據(jù)暫存于內(nèi)存的方式顯著地消除了磁盤開銷,但是GC開銷甚至可以達(dá)到程序運行時間的50%.如圖6所示為程序執(zhí)行過程中Java Heap中數(shù)據(jù)的變化趨勢.可以看到,當(dāng)將RDD以非序列化形式(MEMORY_ONLY)儲存于內(nèi)存時,隨著執(zhí)行,Java Heap中存活的數(shù)據(jù)穩(wěn)步提升.對120 GB Java Heap,伴有大量存活的、非序列化RDD存在時,一次Full GC甚至消耗了128 s的時間.
Fig. 6 Alive memory volume after each GC圖6 每次GC后Java Heap中存活的數(shù)據(jù)
為了消除Storage Memory造成的GC開銷,將一些訪問不頻繁的數(shù)據(jù)序列化,然后再儲存在內(nèi)存中.此時,一個原為眾多獨立對象構(gòu)成的RDD變?yōu)榱艘粋€單一的byte array,極大地減少了需要GC的對象數(shù)量,減少了單次GC的開銷.同時由于壓縮了Storage Memory所占用的內(nèi)存空間,也減少了GC頻率.
因為Storage Memory中的很多數(shù)據(jù)訪問并不頻繁,可以利用NVM來對其進(jìn)行存儲.Spark Tungston利用Unsafe接口,開發(fā)了Spark Off Heap機制.即將使用不頻繁的持久化RDD序列化后存儲于Off Heap,此時只有一些訪問非常頻繁的數(shù)據(jù)仍在Java Heap中.本文便利用該接口開發(fā)了管理Storage Memory的NVM API(NVM_OFF_HEAP).圖6展示了將大量持久化RDD置于Off Heap后,Java Heap中數(shù)據(jù)的變化趨勢.此時可看到,由Execution Memory數(shù)據(jù)主導(dǎo)的Java Heap會被GC頻繁的清空,極大地減少了長時間存活、訪問不頻繁的數(shù)據(jù).從而在單次GC開銷、GC頻率兩方面緩解了GC開銷.此時,雖然對數(shù)據(jù)的序列化需要造成計算開銷,但是對于100GB+的大規(guī)模計算來說,GC開銷占據(jù)了主導(dǎo).如圖7所示,將訪問不頻繁的RDD序列化后,程序加速了29%.通過Off Heap將序列化的Storage Memory數(shù)據(jù)置于NVM時,性能仍舊提升了23%.
Fig. 7 Performance effect of placing storage memory on NVM圖7 使用NVM儲存Storage Memory數(shù)據(jù)后性能
圖7展示了在內(nèi)存中以非序列形式緩存RDD;序列化存儲RDD并置于Java Heap中;序列化RDD置于NVM Off Heap的性能對比.可以看到,使用NVM存儲大量Storage Memory數(shù)據(jù)后(~33 GB),性能并沒有明顯下降(5%以內(nèi)).因此,Spark應(yīng)用開發(fā)人員只需要將常規(guī)的DISK_ONLY,MEMORY_AND_DISK,MEMORY_AND_DISK_SER等帶“DISK”、“SER”關(guān)鍵字的Storage Level直接替換為本文擴展出的NVM_OFF_HEAP便可利用廉價、低功耗的NVM達(dá)到接近無限D(zhuǎn)RAM的速度.此時NVM的使用,不但緩解了DRAM密度難以跟隨計算規(guī)模擴展,必須使用磁盤帶來的開銷;也減少了價格昂貴、功耗過高的DRAM的使用.
將大量序列后的Storage Memory數(shù)據(jù)從DRAM移動到NVM后性能并沒有顯著下降的原因在于,這些數(shù)據(jù)本身并不會被頻繁的訪問;同時序列化操作需要耗費一定的CPU計算資源,進(jìn)一步緩解了對內(nèi)存帶寬上限的需求.在儲存33 GB左右的Storage Memory數(shù)據(jù)于NVM時,其讀帶寬峰值僅為535 MBps左右,如圖8所示.但是,通過4.2節(jié)的分析可知,此時若不使用NVM而是將數(shù)據(jù)直接置于磁盤,則會帶來顯著的性能下降,因為NVM的訪存延遲遠(yuǎn)遠(yuǎn)高于磁盤.
Fig. 8 NVM read bandwidth of placing partial storage memory on NVM圖8 部分Storage Memory置于NVM后NVM讀帶寬
4.4.2 針對Spark Execution Memory的管理
Spark Execution Memory仍舊使用了巨量的內(nèi)存(~80 GB),同時Execution Memory只能使用Java Heap中的內(nèi)存.根據(jù)我們在4.3節(jié)的分析可知,即使在物理內(nèi)存充足時,過小的Java Heap仍舊會因為頻繁的GC而造成性能顯著下降.因此需要利用NVM接近DRAM的性能來擴展Java Heap,以保證Execution Memory有充足的內(nèi)存使用.但在該過程中,我們發(fā)現(xiàn)Execution Memory中的數(shù)據(jù)造成了頻繁的內(nèi)存訪問.如圖9所示,僅將Storage Memory中的大部分?jǐn)?shù)據(jù)遷移到NVM后,DRAM端的Read Bandwidth帶寬峰值可達(dá)15.4 GBps,此時遠(yuǎn)超了NVM的帶寬.因此,如果直接NVM替代DRAM來存儲Java Heap中的數(shù)據(jù),會導(dǎo)致性能下降達(dá)55%左右;使用DRAM和NVM組成的異質(zhì)內(nèi)存,當(dāng)程序隨機使用二者時,也會有32%的性能下降,如圖10所示.所以,需要合理布局其中的冷熱數(shù)據(jù),減少對NVM的讀、寫,防止因為NVM性能不如DRAM而導(dǎo)致新的性能瓶頸.
Fig. 9 DRAM read bandwidth of placing partial storage memory on NVM圖9 部分Storage Memory置于NVM后DRAM讀帶寬
Fig. 10 Performance effect of utilizing heterogeneous memory programming framework圖10 使用異質(zhì)內(nèi)存編程框架后的性能
由于Execution Memory中的數(shù)據(jù)均在Java Heap中,因此其訪存特點受到Java Heap的管理特點影響.本文根據(jù)文獻(xiàn)[44]中的研究,進(jìn)一步對大規(guī)模的分布式系統(tǒng)的訪問行為進(jìn)行了分析.發(fā)現(xiàn)在運行Spark程序時,其Heap中的冷、熱區(qū)域劃分仍舊基本符合文獻(xiàn)[44]中的結(jié)論.不同的是,MetaData Space(元數(shù)據(jù)區(qū))由于遠(yuǎn)大于cache大小,也會造成可觀的訪存行為.因此,該框架將新生代和元數(shù)據(jù)區(qū)直接映射到DRAM區(qū)域,如圖2所示.同時,為了限制使用過多的DRAM,該框架會根據(jù)DRAM可用容量限制新生代的大小,使其可被DRAM容納.此時雖然會造成更頻繁的minor GC(新生代GC),但相比于將部分新生代至于NVM造成的帶寬瓶頸,仍舊會帶來較好的性能.
經(jīng)過針對Storage Memory,Execution Memory中數(shù)據(jù)的布局,在僅使用20%的DRAM時,可以達(dá)到全部使用DRAM 90%的性能,如圖10所示.此時,根據(jù)表3中列出的DRAM,NVM價格比,此時的“性能價格”比例是全部使用DRAM的2.9倍.更為重要的是,和DRAM不足必須使用磁盤時的性能對比,該框架將性能提高了88%,即通過使用該編程框架來利用NVM有效緩解了因為DRAM容量難以提升而限制內(nèi)存計算規(guī)模擴展的問題.
在4.2~4.4節(jié)的分析中,實驗規(guī)模單節(jié)點可達(dá)128 GB,我們將在本節(jié)討論如果計算規(guī)模持續(xù)增加到TB級別,該框架是否繼續(xù)有效.
當(dāng)通過多節(jié)點擴展計算規(guī)模時,雖然整體加速比可能有所變化,但是單個節(jié)點的計算行為仍和4.2~4.4節(jié)分析的相似.除此之外,多節(jié)點間通信可能造成一些新的問題.但是,根據(jù)文獻(xiàn)[47]的分析,多節(jié)點間的數(shù)據(jù)傳輸并不是大數(shù)據(jù)計算的顯著瓶頸,其結(jié)論為通過優(yōu)化網(wǎng)絡(luò),預(yù)期可以得到的加速比僅為2%左右.大數(shù)據(jù)計算的主要瓶頸仍舊在計算、訪存、磁盤等方面.因此,可以認(rèn)為,上述對磁盤、GC、訪存行為的優(yōu)化,在眾多節(jié)點時仍預(yù)計可以取得較好性能.
當(dāng)單節(jié)點的計算規(guī)模繼續(xù)增大時.限制該編程框架的性能因素主要來自于,NVM是否會因為性能較差和磁盤一樣再次成為限制CPU計算的瓶頸.本節(jié)通過NVM訪存延遲較大、帶寬較小2個方面來進(jìn)行討論.
4.5.1 NVM高延遲的影響
Fig. 12 NVM memory read bandwidth variation on different input data size and Java Heap size圖12 NVM讀請求訪存帶寬在不同輸入集和Java Heap Size下的變化
當(dāng)程序的訪存不規(guī)律時,每次cache miss都可能都會造成單獨的訪存,同時也無法通過硬件、軟件預(yù)取來降低訪存開銷.因此,可以認(rèn)為,最差情況下單位時間NVM內(nèi)訪存數(shù)目的增加便會造成性能成比例的下降.因此,本節(jié)統(tǒng)計每執(zhí)行千條指令時NVM訪存數(shù)目是否隨著計算規(guī)模增長而迅速增加.圖11展示了每千條指令中的NVM Load Miss,和Total Load Miss隨著計算規(guī)模增長的變化趨勢.可以看到,隨著Java Heap和輸入集大小的快速增加(指數(shù)級),NVM上的每千條指令中讀請求數(shù)目僅是輕微增加.NVM之上的讀請求和總的讀請求比例基本保持一個恒定值.根據(jù)分析,從20 GB Java Heap增加到40 GB Java Heap時,NVM讀請求的比例增加可能是由于隨著輸入集的增大,Cache逐漸失效的原因.隨后規(guī)模的計算中,Total Load MissK-Ins,NVM Load MissK-Ins逐漸穩(wěn)定.因此,有理由相信,即使計算規(guī)模繼續(xù)指數(shù)增大,也不會因為NVM的較高訪問延遲造成顯著的性能瓶頸.
Fig. 11 NVM access frequency圖11 NVM 訪問頻度
4.5.2 NVM 低帶寬的影響
根據(jù)目前的資料,NVM的帶寬較DRAM較小,但是有的研究認(rèn)為,NVM的帶寬可以通過工藝的提升最終達(dá)到DRAM的水平.本文假設(shè)NVM帶寬為一個較小值,僅為當(dāng)前DRAM帶寬峰值的16左右[2-3](DRAM 1 867 MHz,4通道,~60 GBps),為10 GBps.如圖12中為Java Heap在40GB60GB80GB時NVM中讀請求帶寬趨勢的對比.
從圖12中可以看到,帶寬峰值都在7 GBps左右,沒有隨計算規(guī)模增大而迅速增大的趨勢.我們認(rèn)為,這是因為在一定的計算行為下,訪存帶寬受到了CPU計算能力的限制.在現(xiàn)階段,單CPU的計算能力很難維持摩爾定律成指數(shù)增長.因此,在單個節(jié)點上,NVM 10 GBps左右的帶寬,已經(jīng)可以滿足內(nèi)存計算規(guī)模的繼續(xù)增加.如果隨著工藝發(fā)展,NVM的帶寬繼續(xù)增加,那么其帶寬可能將不再構(gòu)成內(nèi)存計算的性能瓶頸.
綜上分析,我們認(rèn)為本文提出的面向異質(zhì)內(nèi)存的Spark計算框架具有良好的擴展性.可以解決DRAM容量無法滿足內(nèi)存計算需求的問題.
將內(nèi)存中的數(shù)據(jù)序列化雖然會減少GC開銷和磁盤IO開銷,但是會給CPU帶來額外的計算壓力.當(dāng)內(nèi)存容量足夠、GC較少發(fā)生、磁盤IO開銷較少時,序列化并不會帶來整體的性能提升.因此如何平衡二者,需要根據(jù)具體的應(yīng)用特點進(jìn)行具體分析.同時,對于一些程序,其對NVM的使用主要通過擴展Java Heap來減少GC開銷.經(jīng)Off Heap,序列化寫入NVM的數(shù)據(jù)相對較少,因此使用本文的異質(zhì)內(nèi)存編程框架后,并不會帶來過多的序列化開銷.
根據(jù)目前的研究表明,對于內(nèi)存使用量較大的內(nèi)存計算應(yīng)用來說,由于其需要處理巨量的、長期存活的object,GC開銷甚至占據(jù)了大數(shù)據(jù)應(yīng)用運行時間的50%以上[5-6],是限制其性能的主要瓶頸.而內(nèi)存計算應(yīng)用由于需要將一些中間結(jié)果緩存于內(nèi)存中,進(jìn)一步加劇了GC開銷.因此華中科技大學(xué)[38]、Spark Tungston[34]甚至分別提出了將大量數(shù)據(jù)序列化后壓縮為byte array,并直接在其上進(jìn)行計算的方式來減少Java Heap中object數(shù)量,以便減少GC開銷,提升應(yīng)用整體性能.
針對該問題,我們在128 GB內(nèi)存規(guī)模上進(jìn)行了實際的實驗和分析.對于Spark PageRank程序,當(dāng)將絕大多數(shù)RDD改變?yōu)樾蛄谢绞骄彺鏁r(從MEMORY_ONLY改為MEMORY_ONLY_SER),如圖13所示,程序的整體性能提升了29%,即使將序列化后的數(shù)據(jù)置于NVM Off Heap,也會帶來23%的性能提升,如圖7所示.
Fig. 13 Change PageRank’s RDD storage status to serialization mode圖13 將PageRank中的RDD改為序列化形式緩存
這是由于,GC過程中,其需要按照object引用關(guān)系來尋找所有存活的object,而大數(shù)據(jù)應(yīng)用中存活的object數(shù)量巨大,每次GC均會造成顯著的GC開銷.而只需要經(jīng)過一次序列化,大量的object被壓縮為單一的byte array,減少了每次GC的開銷;而經(jīng)過序列化壓縮后,數(shù)據(jù)大小顯著降低,便減少了GC的頻率;最后,GC需要將長期存活的object在eden,from,to,old區(qū)域之間移動.而序列化顯著地壓縮了這些長期存活的RDD數(shù)據(jù)大小,減少了數(shù)據(jù)移動、拷貝帶來的開銷.
因此,對于大數(shù)據(jù)應(yīng)用、內(nèi)存計算應(yīng)用該類消耗內(nèi)存數(shù)量巨大、產(chǎn)生的眾多object的應(yīng)用來說,當(dāng)確定GC為其主要開銷后,將數(shù)據(jù)序列化雖然會給CPU帶來一定的壓力,但是會減少GC帶來的開銷;同時,對數(shù)據(jù)壓縮也會減少磁盤IO的開銷;因此,其會顯著地提升程序的性能.
此外,對于一些程序,在使用本文的異質(zhì)內(nèi)存編程框架后,其通過Off Heap寫入NVM的數(shù)據(jù)并不多.如第5節(jié)中的GraphX程序,由于其緩存的RDD較少,因此在使用本文的框架后并沒有太多的數(shù)據(jù)寫入到Off Heap中.此時NVM主要用來對Java Heap進(jìn)行擴展,減少GC的頻度和磁盤IO的使用.
最后,開發(fā)人員可以通過OpenJDK輸出的GC Log信息快速判斷GC造成的開銷比例.當(dāng)DRAM內(nèi)存充足,GC、磁盤IO并非程序主要開銷時,開發(fā)人員只需要不調(diào)用我們提供的API,便不會帶來額外的序列化開銷.此時,仍可以通過命令-XyoungGenDRAM來開啟OpenJDK層次的數(shù)據(jù)自動布局.
在第4節(jié)的分析中使用了搜索引擎離線分析程序,Spark PageRank,進(jìn)行性能分析.本節(jié)將分析在不同的Spark應(yīng)用中,提出編程框架是否仍然有效.
首先,針對圖計算Spark-GraphX進(jìn)行性能分析.這里選用其中的ConnectedComponents算法來進(jìn)行性能分析.其亦為迭代計算,不同于Spark PageRank,Spark-GraphX計算過程中,其僅僅保留上一次迭代的持久化RDD,并將前面的持久化RDD釋放掉.因此,這里并沒有太多持久化的RDD在Java Heap中,沒有必要使用NVM_OFF_HEAP接口.為了使應(yīng)用的Memory Footprint達(dá)到120 GB,這里選用了更大規(guī)模的輸入集:3 GB大小.
在測試中發(fā)現(xiàn),僅使用32GB物理內(nèi)存時,應(yīng)用運行時間過長,因此將其擴展為60 GB,并將Executor限制為40 GB.即使該配置下,Connected Components消耗的時間也過長,這里并沒有最終執(zhí)行完.由于并沒有OFF_HEAP空間的使用,因此異質(zhì)內(nèi)存的對比試驗設(shè)置為30 GB DRAM+98 GB NVM,Executor (Java Heap)直接設(shè)置為120 GB.運行結(jié)果如圖14所示.可以看到,此時雖然Spark-GraphX沒有大量的使用Storage Memory,但是本文提出的框架在用25%的DRAM情況下,性能比全部使用DRAM僅慢了9%.而且比DRAM不足(僅為40 GB DRAM)時,加速可達(dá)300%以上.由于利用Spark-GraphX的應(yīng)用的訪存行為較為類似,因此本節(jié)在這里僅測試了ConnectedComponents.從此可以看到,即使Spark應(yīng)用為Storage Memory使用較少,NVM主要用于擴展Java Heap時,本文提出的面向異質(zhì)內(nèi)存的Spark編程框架仍舊可以取得很好地效果.
Fig. 14 Spark-GraphX performance comparison of utilizing enough DRAM, not enough DRAM and heterogeneous memory圖14 Spark-GraphX在充足DRAM、DRAM不足、異質(zhì)內(nèi)存情況下的性能對比
本節(jié)使用Big DataBench中的K-means進(jìn)行性能分析,其同樣為迭代計算.其中的持久化RDD分為2類,直接以非序列化形式置于Java Heap中的頻繁訪問RDD.Storage Level為MEMORY_AND_DISK的,可以存放于磁盤的RDD.在異質(zhì)內(nèi)存中,本節(jié)將后者替換為NVM_OFF_HEAP來進(jìn)行試驗.但是經(jīng)過分析發(fā)現(xiàn),其產(chǎn)生的Storage memory仍然明顯少于Spark PageRank.實驗結(jié)果如圖15所示,在使用25%的DRAM后,其性能僅僅降低了6%,比DRAM容量不足時加速52%.
Fig. 15 Spark K-means performance comparison of utilizing enough DRAM, not enough DRAM and heterogeneous memory圖15 Spark K-means在充足DRAM、DRAM不足、異質(zhì)內(nèi)存情況下的性能對比
經(jīng)過本節(jié)的分析可以看到,異質(zhì)內(nèi)存編程框架在Spark,OpenJDK兩個層次進(jìn)行的異質(zhì)內(nèi)存數(shù)據(jù)布局,在搜索引擎離線分析(Spark PageRank)、圖計算(Spark GraphX)、社交網(wǎng)絡(luò)分析(SparkK-means)領(lǐng)域具有較好的結(jié)果.這是由于,在Spark層次,由于Spark程序的主要數(shù)據(jù)結(jié)構(gòu)(RDD)簡潔、計算行為規(guī)則,Spark應(yīng)用開發(fā)人員較易識別出冷熱數(shù)據(jù),并調(diào)用本文提供的接口來將特定的RDD置于NVM中,降低GC開銷;在OpenJDK層次,由于Spark運行于JVM,因此這些應(yīng)用的訪存特性均受到了OpenJDK對內(nèi)存管理的影響.因此本文通過分析Java Heap內(nèi)存管理特點給出的數(shù)據(jù)映射方案對這些應(yīng)用均具有一定的效果.將熱數(shù)據(jù)置于DRAM、冷數(shù)據(jù)置于NVM后,并沒有因為NVM的性能不如DRAM而造成較大的性能下降.同時,利用NVM擴展Java Heap容量后,顯著地降低了GC的頻率.由于時間限制,我們沒能測試更多的用例,在隨后的工作中我們會擴大實驗對象,進(jìn)一步分析方法的局限性.
本文提出的框架可以很好的處理Spark離線分析應(yīng)用,尤其是對于迭代形式的Spark程序具有很好的效果.在僅使用20%~25%的DRAM時,相比于全部使用DRAM,性能僅下降10%左右.對比DRAM不夠頻繁訪問磁盤時的情況,使用NVM擴展內(nèi)存容量后,性能加速可達(dá)88%.但對于一些在線處理的應(yīng)用,比如在線查找等,其需要快速返回結(jié)果給用戶,該框架可能導(dǎo)致一定比例的用戶得到結(jié)果的延遲較大,從而造成較差的使用體驗.對于該類應(yīng)用,需要動態(tài)地對數(shù)據(jù)進(jìn)行遷移來進(jìn)一步提升性能.我們將在隨后的工作中繼續(xù)探討如何解決該類問題.
[1]Grandpierre M, Buss G, Esser R. In-Memory Computing technology. The holy grail of analytics?[R]. Berlin: Deloitte, 2013
[2]Zilberberg O, Weiss S, Toledo S. Phase-change memory: An architectural perspective[J]. ACM Computing Surveys, 2013, 45(3): 1-33
[3]Dulloor S R, Roy A, Zhao zheguang, et al. Data tiering in heterogeneous memory systems[C] //Proc of the 11th European Conf on Computer Systems. New York: ACM, 2016: No.15
[4]Apache Spark. A fast and general engine for large-scale data processing[EB/OL]. [2017-09-10]. http://spark.apache.org/
[5]Nguyen K, Lü Fang, Xu Guoqing, et al. Yak: A high-performance big-data-friendly garbage collector[C] //Proc of the 12th USENIX Conf on Operating Systems Design and Implementation. Berkeley, CA: USENIX, 2016: 349-365
[6]Nguyen K, Wang Kai, Bu Yingyi, et al. FACADE: A compiler and runtime for (Almost) object-bounded big data applications[C] //Proc of the 12th Int Conf on Architectural Support for Programming Languages and Operating Systems. New York: ACM, 2015: 675-690
[7]BigDataBench. A Big Data Benchmark Suite, ICT, Chinese Academy of Sciences [EB/OL]. [2017-09-10]. http://prof.ict.ac.cn/
[8]Wei Wei, Jiang Dejun, Sally A M, et al. Exploiting program semantics to place data in hybrid memory[C] //Proc of the Int Conf on Parallel Architecture and Compilation. Piscataway, NJ: IEEE, 2015: 163-173
[9]Apache Hadoop. Open-source software for reliable, scalable, distributed computing [EB/OL]. [2017-09-10]. http://hadoop.apache.org/
[10]Lu Youyou, Shu Jiwu. Survey on flash-based storage systems[J]. Journal of Computer Research and Development, 2013, 50(1): 49-59 (in Chinese)(陸游游, 舒繼武. 閃存存儲系統(tǒng)綜述[J]. 計算機研究與發(fā)展, 2013, 50(1): 49-59)
[11]Shu Jiwu, Lu Youyou, Zhang Jiacheng, et al. Research progress on non-volatile memory based storage system[J]. Science & Technology Review, 2016, 34(14): 86-94 (in Chinese)(舒繼武, 陸游游, 張佳程, 等. 基于非易失性存儲器的存儲系統(tǒng)技術(shù)研究進(jìn)展[J]. 科技導(dǎo)報, 2016, 34(14): 86-94)
[12]Xia Fei, Jiang Dejun, Xiong jin. Evaluating and analyzing the performance of nonvolatile memory system[J]. Journal of Computer Research and Development, 2014, 51(Suppl 1): 25-31 (in Chinese)(夏飛, 蔣德鈞, 熊勁. 影響非易失性內(nèi)存系統(tǒng)性能的因素分析[J]. 計算機研究與發(fā)展, 2014, 51(增1): 25-31)
[13]Xu Yuanchao, Yan Junfeng, Wan Hu, et al. A survey on security and privacy of emerging non-volatile memory[J]. Journal of Computer Research and Development, 2016, 53(9): 1930-1942 (in Chinese)(徐遠(yuǎn)超, 閆俊峰, 萬虎, 等. 新型非易失存儲的安全與隱私問題研究綜述[J]. 計算機研究與發(fā)展, 2016, 53(9): 1930-1942)
[14]Zhang Tiefei, Chen Tianzhou, Wu Jianzhong. Exploiting memory access patterns of programs for energy-efficient memory system techniques[J]. Journal of Software, 2014, 25(2): 254-266(章鐵飛, 陳天洲, 吳劍鐘. 基于程序訪存模式的低功耗存儲技術(shù)[J]. 軟件學(xué)報, 2014, 25(2): 254-266)
[15]Qureshi M K, Srinivasan V, Rivers J. Scalable high performance main memory system using phase-change memory technology[C] //Proc of the 36th Annual Int Symp on Computer Architecture. New York: ACM, 2009: 24-33
[16]Zhou Ping, Zhao Bo, Yang Jun, et al. A durable and energy efficient main memory using phase change memory technology[C] //Proc of the 36th Annual Int Symp on Computer Architecture. New York: ACM, 2009: 14-23
[17]Kgil T, Roberts D, Mudge T. Improving NAND flash based disk caches[C] //Proc of the 35th Annual Int Symp on Computer Architecture. Piscataway, NJ: IEEE, 2008: 327-338
[18]Mangalagiri P, Sarpatwari K, Yanamandra A, et al. A low-power phase change memory based hybrid cache architecture[C] //Proc of the 18th ACM Great Lakes Symp on VLSI. New York: ACM, 2008: 395-398
[19]Lee B C, Ipek E, Mutlu O, et al. Architecting phase change memory as a scalable dram alternative[C] //Proc of the 36th Annual Int Symp on Computer Architecture. New York: ACM, 2009: 2-13
[20]Ramos L, Gorbatov E, Bianchini R. Page placement in hybrid memory systems[C] //Proc of the Int Conf on Supercomputing. New York: ACM, 2011: 85-95
[21]Lebeck A, Fan Xiaobo, Zeng Heng, et al. Power aware page allocation[J]. ACM SIGPLAN Notices, 2000, 35(11): 105-116
[22]Huang Hai, Pillai P, Shin K. Design and implementation of power-aware virtual memory[C]//Proc of the Conf on USENIX Annual Technical Conf. Berkeley, CA: USENIX, 2003: 5-5
[23]Zhang Wangyuan, Li Tao. Exploring phase change memory and 3D die-stacking for power/thermal friendly, fast and durable memory architectures[C]//Proc of the 18th Int Conf on Parallel Architectures and Compilation Techniques. Piscataway, NJ: IEEE, 2009: 101-112
[24]Pandey V, Jiang W, Zhou Y, et al. DMA-aware memory energy management[C]//Proc of the 12th Int Symp on High-Performance Computer Architecture. Piscataway, NJ: IEEE, 2006: 133-144
[25]Sivathanu M, Prabhakaran V, Popovici F, et al. Semantically-smart disk systems[C] //Proc of the 2nd USENIX Conf on File and Storage Technologies. Berkeley, CA: USENIX, 2003: 73-88
[26]Mesnier M, Akers J. Differentiated storage services[J]. ACM SIGOPS Operating Systems Review, 2011, 45(1): 45-53
[27]Hassan A, Vandierendonck H, Nikolopoulos D. Software-managed energy-efficient hybrid DRAM/NVM main memory[C] //Proc of the 12th ACM Int Conf on Computing Frontiers. New York: ACM, 2015: No.23
[28]Piccoli G, Santos H, Rodrigues R, et al. Compiler support for selective page migration in NUMA architectures[C]//Proc of the Int Conf on Parallel Architectures and Compilation. New York: ACM, 2014: 369-380
[29]Dulloor S, Kumar S, Keshavamurthy A, et al. System software for persistent memory[C] //Proc of the 9th European Conf on Computer Systems. New York: ACM, 2014: No.15
[30]Huang Hai, Shin K, Lefurgy C, et al. Improving energy efficiency by making DRAM less randomly accessed[C] //Proc of the 2005 Int Symp on Low power electronics and design. New York: ACM, 2005: 393-398
[31]Appel A W. Simple generational garbage collection and fast allocation[J]. Software Practice and Experience, 1989, 19(2): 171-183
[32]StefanoviC D, McKinley Kand J, Moss J. Age-based garbage collection[C] //Proc of the 14th ACM SIGPLAN Conf on Object-Oriented Programming, Systems, Languages, and Applications. New York: ACM, 1999: 370-381
[33]Bu Yingyi, Borkar V, Xu Guoqing, et al. A bloat-aware design for big data applications[C] //Proc of the 2013 Int Symp on Memory Management. New York: ACM, 2013: 119-130
[34]Databricks. Project Tungsten: Bringing Apache Spark Closer to Bare Metal [EB/OL]. [2017-09-10]. https://databricks.com/blog/2015/04/28/project-tungsten-bringing-spark-closer-to-bare-metal.html
[35]BeebeeJr W, Rinard M. An implementation of scoped memory for real-time Java[G] //LCNS 2211: Proc of Int Workshop on Embedded Software. Berlin: Springer, 2001: 289-305
[36]Blackburn S, McKinley K. Immix: A mark-region garbage collector with space efficiency, fast collection, and mutator performance[C] //Proc of the 29th ACM SIGPLAN Conf on Programming Language Design and Implementation. New York: ACM, 2008: 22-32
[37]Boyapati C, Salcianu A, Beebee W, et al. Ownership types for safe region-based memory management in real-time Java[J]. ACM SIGPLAN Notices, 2003, 38(5): 324-337
[38]Lu Lu, Shi Xuanhua, Zhou Yongluan, et al. Lifetime-based memory management for distributed data processing systems[J]. VLDB Endowment, 2016, 9(12): 936-947
[39]Gao Tiejun, Strauss K, Blackburn S, et al. Using managed runtime systems to tolerate holes in wearable memories[C] //Proc of the 34th ACM SIGPLAN Conf on Programming Language Design and Implementation. New York: ACM, 2013: 297-308
[40]Nakagawa G, Oikawa S. An analysis of the relationship between a write access reduction method for NVM/DRAM hybrid memory with programming language runtime support and execution policies of garbage collection[C] //Proc of the IIAI 3rd Int Conf on Advanced Applied Informatics. Piscataway, NJ: IEEE, 2014: 597-603
[41]Nakagawa G, Oikawa S. Language runtime support for NVM/DRAM hybrid main memory[C] //Proc of the IEEE COOL Chips XVII. Piscataway, NJ: IEEE, 2014: 1-3
[42]Nakagawa G, Oikawa S. NVM/DRAM hybrid memory management with language runtime support via MRW queue[C] //Proc of the Software Engineering, Artificial Intelligence, Networking and Parallel/Distributed Computing (SNPD). Piscataway, NJ: IEEE, 2015: 1-6
[43]Nakagawa G, Oikawa S. Preliminary analysis of a write reduction method for non-volatile main memory on jikes RVM[C] //Proc of the 1st Int Symp on Computing and Networking. Piscataway, NJ: IEEE, 2013: 597-601
[44]Wang Chenxi, Cao Ting, Zigman J, et al. Efficient management for hybrid memory in managed language runtime[G] //LNCS 9966: Proc of the IFIP Int Conf on Network and Parallel Computing. Berlin: Springer, 2016: 29-42
[45]Yang Ting, Hertz M, Berger E, et al. Automatic heap sizing: Taking real memory into account[C] //Proc of the 4th Int Symp on Memory Management. New York: ACM, 2004: 61-72
[46]Hertz M, Feng Yi, Berger E. Garbage collection without paging[C] // Proc of the Programming Language Design and Implementation. New York: ACM, 2005: 143-153
[47]Ousterhout K, Rasti R, Ratnasamy S, et al. Making sense of performance in data analytics frameworks[C] //Proc of the 12th USENIX Symp on Networked Systems Design and Implementation. Berkeley, CA: USENIX, 2015: 293-307