MapReduce計算框架中的高性能排序方法
【專利摘要】本發明涉及一種MapReduce計算框架中的高性能排序方法。該方法在Map階段按照partition分別構建緩沖鏈,移除partition本身進行排序的需要,并且對于每一個partition數據將按照塊進行組織,降低了數據在內存中的拷貝以及文件IO方面的代價;在Map階段不執行排序操作,在Reduce階段以一個較大的緩沖池作為一次排序的基本單位,使得在排序的歸并階段總的歸并路數是一個用戶可調優的值。本發明通過一種混合的內存排序算法,優化了MapReduce框架中排序的兩個階段,基本消除了排序對于計算框架的性能影響,進而提升了計算框架的資源有效性,降低了集群的整體資源消耗。
【專利說明】MapReduce計算框架中的高性能排序方法
【技術領域】
[0001]本發明屬于信息【技術領域】,涉及一種對分布式計算框架的優化方法,特別涉及一種在MapReduce計算框架中提高排序性能的方法。
【背景技術】
[0002]MapReduce是分布式計算中的一種標準框架,但在資源消耗方面,現有MapReduce框架并不高效,導致大量集群資源被浪費。
[0003]現有MapReduce框架中需要對中間數據的key/value對進行排序,并且排序構成了現有計算框架中主要的資源消耗。我們以MapReduce的開源實現hadoop為例,說明上述問題。
[0004]如圖1所示,為傳統MapReduce數據流程示意圖。其中Hadoop文件系統(簡稱HDFS,Hadoop File System)負責數據的分布式存儲。計算框架所執行任務(Job)從HDFS讀入數據經過處理后再寫入到HDFS。在計算框架內部分為Map和Reduce兩個階段,Map階段將HDFS上的數據執行用戶自定義的Map函數,然后對輸出的中間數據首先放入內存,然后排序后寫入本地磁盤。在Reduce階段,每個Reduce接收來自各個Map的排序后的中間數據然后進行歸并。框架對同一 key下的所有value調用用戶自定義的Reduce函數進行計算后寫入到HDFS。具體的數據流程可以參見圖1。
[0005]在如圖1所示的原有的數據流程中,排序所需要的工作量3,5,7,8消耗了大部分的框架CPU資源。這種消耗又可以分為內存排序和多路歸并兩個階段。
[0006]1、流程3中對中間數據進行基于內存的二級索引快速排序。排序的過程實際上是對16字節的索引進行排序,索引為一個四元組〈id, partition, key offset, valueoffset〉。當兩個這樣的四元組進行比較時首先比較兩條記錄的partition,構成一個partition 升序的序列。只有當 partition—致時再根據〈key offset, value offset〉找到對應的key進行字節比較。大量冗余的partition比較以及O(nlogn)復雜度的代價使得這一部分效率很低。
[0007]2、流程5,7,8中對內存或磁盤上的有序數據進行多路歸并排序。由于在MapReduce計算框架中需要保證內存有限時對數據依舊可以處理,因此基于磁盤的歸并排序是框架必不可少的一部分。這一部分的算法實現的復雜度為O(nlogm),其中η為記錄數而m為歸并路數。由于整體所需要排序的記錄數固定,因此這一部分是否高效取決于歸并路數,而歸并路數在現有實現中其最小值和map的數目相當。對于map數目較大的Job,這部分的代價會高于第一部分的代價并消耗大部分資源。
[0008]因此,在現有MapReduce計算框架中進行排序的兩個階段因為算法的選擇或是處理流程上的不當導致都不高效,而排序操作又對于每一個Job都必不可少,造成了大量的資源浪費。
【發明內容】
[0009]本發明目的在于提出一種在MapReduce計算框架中進行的高性能排序方法,能夠降低框架整體的CPU資源消耗,提高集群整體有效利用率。
[0010]本發明的MapReduce計算框架中的高性能排序方法,其步驟包括:
[0011]1、Map Task從HDFS上讀取文件,構造輸入數據的key/value對;
[0012]2、對輸入數據執行用戶自定義Map函數并輸出中間結果的key/value對,并計算key所對應的partition ;對內存中每個partition設置對應的緩沖鏈,將中間結果的key/value對首先計算長度,然后插入到緩沖鏈中;
[0013]3、當內存無法放下所有中間結果的key/value對時,按照partition的順序,輸出所有緩沖鏈到本地文件;
[0014]4、對經過上述步驟后在內存和本地磁盤上形成的一個或多個未排序的結果按照partition的順序進行歸并,輸出成一個完整的按照partition進行分段的本地文件;
[0015]5、Reduce Task通過AppMaster獲得Map Task結束的信息,向負責該Map數據托管的進程發送http請求,拖取該Map輸出的中間數據中屬于該Reduce的部分,將這些數據根據其大小選擇放于內存或放于本地磁盤;
[0016]6、將內存或磁盤中的中間數據讀入內存中的排序緩沖池,當排序緩沖池滿時,對整個緩沖池進行排序;
[0017]7、對于中間數據無法全部放在一個排序緩沖池中的情況,在排序后將數據寫出到本地文件中。
[0018]進一步地,上述方法還包括如下步驟:
[0019]8、對內存和本地文件中的有序結果進行歸并,歸并結果作為用戶自定義Reduce函數的輸入;
[0020]9、Reduce函數對相同key下的所有value執行操作,生成輸出數據的key/value對并寫入HDFS。
[0021]進一步地,步驟6)對于大多數作業使用的整形或者字符數組類型的key,抽取key中能夠保序的4字節作為低32位,和該條記錄本身4字節的二級索引作為高32位進行拼接,形成一個8字節的長整形作為新的key。更進一步地,在這個8字節上使用基數排序,使得其從key中抽取的4字節有序。更進一步地,獲取基數排序后的二級索引,再對其進行快速排序保證整體記錄的有序性。
[0022]進一步地,步驟6)對于無法抽取保序4字節的key類型,構建二級索引,使用快速排序進行整體記錄的排序。
[0023]其中,抽取key中4字節的方法是:對于整數即其本身;對于字符數組類型的key為其排序序列的前4個字節,以整數對待,并在最高位取反。
[0024]其中,基數排序算法為非遞歸版本,輸入為兩個長整形的數組,一個用于存放原始數據,一個用于算法的臨時空間,算法執行后的結果為長整形數組中低32位整形有序。
[0025]其中,緩沖池的大小和原有實現(圖1所示方法)中的排序緩沖池的大小保持一致,需要用戶設定。
[0026]本發明的有益效果如下:
[0027]1、本發明在Map階段按照partition分別構建緩沖鏈,移除了 partition本身進行排序的需要,并且對于每一個partition數據將按照塊(block)進行組織,降低了數據在內存中的拷貝以及文件IO方面的代價。
[0028]2、本發明在Map階段不執行排序操作,使得Map階段的運行時間和CPU資源消耗大幅度下降,進而整體Map階段的結束時間提前,并且對于大多數作業的整體運行時間得到優化。
[0029]3、本發明在Reduce階段以一個較大的緩沖池作為一次排序的基本單位(例如128MB),使得在排序的歸并階段總的歸并路數是一個用戶可調優的值。對于每個reduce處理數據量一定的情況,歸并路數為一個非常小的常數值(一般為I?4)。因此歸并階段的算法復雜度和消耗的資源都將減少。
[0030]4、本發明通過一種混合的內存排序算法,能夠高效的對內存中變長記錄進行排序。基數排序算法復雜度低但不適合變長字段,快速排序適用性廣但算法復雜度高。結合MapReduce框架場景需要對大量變長的〈key,value)格式的數據進行排序,本發明首先通過低復雜度的基數排序將記錄的定長部分進行排序,然后對于少量無序的記錄再利用快速排序來保證結果的正確性。兩種算法的混合使得既能保證整體的低算法復雜度,又能保證對變長記錄的適用性,提高了整體的排序性能。
[0031]因此,本發明優化了 MapReduce框架中排序的兩個階段,使用高效的內存算法并且降低歸并路數使得整體的排序性能得到大幅度提升,基本消除了排序對于計算框架的性能影響,進而提升了計算框架的資源有效性,降低了集群的整體資源消耗。
【專利附圖】
【附圖說明】
[0032]圖1傳統MapReduce計算框架數據流程圖。
[0033]圖2本發明MapReduce計算框架數據流程圖。
[0034]圖3本發明內存排序方法流程圖。
[0035]圖4本發明數據流程與傳統數據流程性能對比圖。
[0036]圖5本發明混合內存排序算法和傳統快速排序性能對比圖。
[0037]圖6本發明高性能排序方法和傳統框架中排序的資源消耗對比圖。
【具體實施方式】
[0038]下面通過具體實施例和附圖,對本發明做進一步說明。
[0039]本發明是在Hadoop平臺版本2.2上進行的,主要針對MapReduce計算框架中的數據流程進行優化。圖2是本發明MapReduce計算框架數據流程圖。我們分為兩個部分說明實施方式,首先說明為了減少歸并路數將Map階段的排序移至Reduce階段的新數據流程,接著說明混合的高性能內存排序算法的實現細節。
[0040]本發明重新設計了 MapReduce計算框架的數據流程。本發明的工作基于Hadoop進行說明,但本發明對于排序方案的優化也涵蓋其它MapReduce架構的系統。
[0041]對于Map階段,本發明重新設計了 MapOutputBuffer的實現。原始的MapOutputBuffer的功能為接收中間數據三元組〈key, value, partition〉,并最終在本地文件系統上形成一個排序后的文件。但在本發明中MapOutputBuffer的輸入不變,但輸出為一個文件系統上的未排序文件。
[0042]本發明中MapOutputBuffer對每個partition維護一個緩沖鏈,緩沖鏈上的緩沖塊來自于一個共享的緩沖池,在分配過程中,每個緩沖鏈向緩沖池申請一個偏移來鎖定一塊內存區域。對于每一個輸入的三元組,會根據partition確定將要添加到的緩沖鏈,然后首先將〈key,value)序列化得到長度,然后添加到該緩沖鏈的最后。一次添加可能會跨越某個緩沖鏈上的多個緩沖塊。
[0043]在每次添加到緩沖鏈前會做一次檢查,確保有足夠的空間。對于內存不足以容納所有中間數據的情況,我們把所有的緩沖鏈按照partition的順序寫入到一個本地的臨時文件。
[0044]在所有輸入都已經添加之后,我們需要合并內存和臨時文件的數據來形成最終的本件,這種合并將以partition為單位,因此進行合并的次數非常少。而在傳統實現中如果中間數據的條數非常多則會造成額外的代價。
[0045]本發明對于Reduce階段的設計主要是增加一個大的排序緩沖池用來做內存排序。原有實現中,當Map階段所有排序的數據傳輸到Reduce端時會根據大小放在內存或本地磁盤上,每一個這樣的有序數據塊稱為一個Segment。而在本發明中,傳輸的數據塊為未排序的,因此我們需要把每一條記錄都添加到內存的一個大的緩沖區中,只有當緩沖區無法容納更多記錄時,我們對其進行排序,然后將排序后的內容寫出到本地磁盤,形成和原有實現中格式類似的Segment。
[0046]將傳輸的內容添加到排序緩沖池中的操作必須保證不能阻塞,因此在本發明中我們采用雙緩沖結構,當某一個排序緩沖滿了之后,我們會異步的進行排序并寫出,同時另一個排序緩沖會繼續接受傳輸的數據。這種方式很好地并行化了數據通過網絡傳輸的時間以及數據經過排序寫入本地磁盤的時間。
[0047]當所有Segment都構建完成后,會在本地磁盤上形成少數待歸并的有序文件,此時構建內存的堆結構來執行多路歸并的操作。
[0048]圖3是對本發明中使用的內存排序算法的描述,樣例中記錄key為字符數組類型。
[0049]首先在填充排序緩沖池(Sort Buffer (byte []))的時候,會通過一個Hash函數來對每個key得到一個整形的返回值。Hash函數的描述可以參考http://en.wikipedia.0rg/wiki/Hash_function。對于大多數key類型,hash函數為系統自帶,保證了最終的結果和傳統MapReduce —致。對于某些key類型,因為難以定制保序的Hash函數,用戶可以選擇是否放棄結果集的有序性來提升性能。這種情況下,用戶需要自定義Hash函數或者使用系統自帶通用的 MurMurHash (http://en.wikipedia.0rg/wiki/MurmurHash)。
[0050]得到的整形值會和這個記錄在緩沖池中的位置進行拼接,構成一個長整形數組(Index(long[]) )0對于數組的直接的排序操作會比在二級索引上操作更高效。對于這個長整形數組的基數排序算法(Radix sort)只需要保證低4個字節的有序性,當排序完成后高4個字節所代表的索引就是對應記錄應該在整個記錄集中的大致位置。我們將高4字節提取出來得到整形數組。
[0051]因為我們只截取了 key的一部分信息用于排序,因此有可能有部分不同的key但通過Hash函數后得到相同的值。所以我們需要遍歷長整形數組中的低4字節,如果有相同值,我們需要對提取出來的整形數組的對應區域進行額外的一次快速排序(Quick sort)。由于在第一次排序中數據已經基本有序,因此第二次排序所需要比較的key的數目會非常少,所以代價也非常低。[0052]本發明在已有的hadoop基準數據集上進行了測試來驗證,共分為三個部分。第一個測試使用Terasort的數據集在20臺機器的分布式環境中來驗證本發明中Reduce端進行排序的數據流相比原有實現中Map端進行排序數據流的性能優勢。試驗測試了在不同數據量上排序部分的時間差異,我們采用了對數坐標系,并且我們將Map端排序的理論最優值歸一化為I。結果如圖4所示,從中可以看到當數據量增大時,Reduce端進行排序得到的性能效率明顯提升,排序時間上的差異接近3倍。
[0053]第二個測試我們驗證本發明采用的混合內存排序算法相比于單一的快速排序算法性能優勢。該測試我們采用單機的測試環境,使用了通用的排序數據集。實驗結果如圖5所示,在一些比較大的數據集上,兩種算法的性能差異接近10倍。在實際生產環境中,一次排序的數據集大小一般都在100MB以上,因此采用混合的內存排序算法對于降低整體框架的排序資源消耗優勢顯著。
[0054]第三個測試在20臺機器的分布式環境下驗證本發明兩種高性能排序方法的結合在不同作業類型下的表現。我們使用了 HiBench (https://github.com/intel_hadoop/HiBench)基準測試集進行驗證。我們將排序在框架中的資源消耗作為對比項,結果如圖6所示,本發明中的高性能排序方法能夠將大多數作業中排序部分的資源消耗降到5%以內,使得排序部分不再成為集群資源消耗的主要來源。
[0055]以上實施例僅用以說明本發明的技術方案而非對其進行限制,本領域的普通技術人員可以對本發明的技術方案進行修改或者等同替換,而不脫離本發明的精神和范圍,本發明的保護范圍應以權利要求所述為準。
【權利要求】
1.一種MapReduce計算框架中的高性能排序方法,其步驟包括: 1)Map Task從HDFS上讀取文件,構造輸入數據的key/value對; 2)對輸入數據執行用戶自定義Map函數并輸出中間結果的key/value對,并計算key所對應的partition ;對內存中每個partition設置對應的緩沖鏈,將中間結果的key/value對首先計算長度,然后插入到緩沖鏈中; 3)當內存無法放下所有中間結果的key/value對時,按照partition的順序,輸出所有緩沖鏈到本地文件; 4)對經過上述步驟后在內存和本地磁盤上形成的一個或多個未排序的結果按照partition的順序進行歸并,輸出成一個完整的按照partition進行分段的本地文件; 5)Reduce Task通過AppMaster獲得Map Task結束的信息,向負責該Map數據托管的進程發送http請求,拖取該Map輸出的中間數據中屬于該Reduce的部分,將這些數據根據其大小選擇放于內存或放于本地磁盤; 6)將內存或磁盤中的中間數據讀入內存中的排序緩沖池,當排序緩沖池滿時,對整個緩沖池進行排序; 7)對于中間數據無法全部放在一個排序緩沖池中的情況,在排序后將數據寫出到本地文件中。
2.如權利要求1所述的方法,其特征在于,還包括如下步驟: 8)對內存和本地文件中的有序結果進行歸并,歸并結果作為用戶自定義Reduce函數的輸入; 9)Reduce函數對相同key下的所有value執行操作,生成輸出數據的key/value對并寫入HDFS。
3.如權利要求1或2所述的方法,其特征在于:步驟6)對于大多數作業使用的整形或者字符數組類型的key,抽取key中能夠保序的4字節作為低32位,和該條記錄本身4字節的二級索引作為高32位進行拼接,形成一個8字節的長整形作為新的key。
4.如權利要求3所述的方法,其特征在于:在所述8字節上使用基數排序,使得其從key中抽取的4字節有序。
5.如權利要求3所述的方法,其特征在于:所述基數排序算法為非遞歸版本,輸入為兩個長整形的數組,一個用于存放原始數據,一個用于算法的臨時空間,算法執行后的結果為長整形數組中低32位整形有序。
6.如權利要求3所述的方法,其特征在于:獲取基數排序后的二級索引,再對其進行快速排序保證整體記錄的有序性。
7.如權利要求3所述的方法,其特征在于:抽取key中4字節的方法是:對于整數即其本身;對于字符數組類型的key為其排序序列的前4個字節,以整數對待,并在最高位取反。
8.如權利要求3所述的方法,其特征在于:步驟6)對于無法抽取保序4字節的key類型,構建二級索引,使用快速排序進行整體記錄的排序。
9.如權利要求1或2所述的方法,其特征在于,步驟6)采用雙緩沖結構將傳輸的內容添加到排序緩沖池中,以避免阻塞:當某一個排序緩沖滿后,異步地進行排序并寫出,同時另一個排序緩沖繼續接收傳輸的數據。
【文檔編號】G06F17/30GK103995827SQ201410145069
【公開日】2014年8月20日 申請日期:2014年4月10日 優先權日:2014年4月10日
【發明者】蔣達晟, 陳薇, 王騰蛟 申請人:北京大學