Hadoop中TeraSort演算法分析
1、概述
1TB排序通常用于衡量分布式資料處理架構的資料處理能力。Terasort是Hadoop中的的一個排序作業,在2008年,Hadoop在1TB排序基準評估中贏得第一名,耗時209秒。那麼Terasort在Hadoop中是怎樣實現的呢。本文主要從演算法設計角度分析Terasort作業。
2、演算法思想
實際上,當我們要把傳統的串列排序演算法設計成並行的排序演算法時,通常會想到分而治之的策略,即:把要排序的資料劃成M個資料區塊(可以用Hash的方法做到),然後每個maptask對一個資料區塊進行局部排序,之後,一個reducetask對所有資料進行全排序。這種設計思路可以保證在map階段並行度很高,但在reduce階段完全沒有並行。
為了提高reduce階段的並行度,TeraSort作業對以上演算法進行改進:在map階段,每個maptask都會將資料劃分成R個資料區塊(R為reducetask個數),其中第i(i>0)個資料區塊的所有資料都會比第i+1個中的資料大;在reduce階段,第i個reducetask處理(進行排序)所有maptask的第i塊,這樣第i個reducetask產生的結果均會比第i+1個大,最後將1~R個reducetask的排序結果順序輸出,即為最終的排序結果。這種設計思路很明顯比第一種高效,但實現難度較大,它需要解決以下兩個技術痛點:第一,如何確定每個maptask資料的R個資料區塊的範圍。第二,對於某條資料,如果快速的確定它屬於哪個資料區塊。答案分別為【採樣】和【trie樹】。
3、Terasort演算法
3.1Terasort演算法流程
對於Hadoop的Terasort排序演算法,主要由3步組成:採樣–>>maptask對於資料記錄做標記–>>reducetask進行局部排序。
資料採樣在JobClient端進行,首先從輸入資料中抽取一部分資料,將這些資料進行排序,然後將它們劃分成R個資料區塊,找出每個資料區塊的資料上限和下線(稱為“分割點”),並將這些分割點儲存到分布式緩衝中。
在map階段,每個maptask首先從分布式緩衝中讀取分割點,並對這些分割點建立trie樹(兩層trie樹,樹的葉子節點上儲存有該節點對應的reducetask編號)。然後正式開始處理資料,對於每條資料,在trie樹中尋找它屬於的reducetask的編號,並儲存起來。
在reduce階段,每個reducetask從每個maptask中讀取其對應的資料進行局部排序,最後將reducetask處理後結果按reducetask編號依次輸出即可。
3.2Terasort演算法關鍵點(1)採樣
Hadoop內建了很多資料採樣工具,包括IntercalSmapler,RandomSampler,SplitSampler等(具體見org.apache.hadoop.mapred.lib)。
採樣資料條數:sampleSize=conf.getLong(“terasort.partitions.sample”,100000);
選取的split個數:samples=Math.min(10,splits.length);splits是所有split組成的數組。每個split提取的資料條數:recordsPerSample=sampleSize/samples;
對採樣的資料進行全排序,將擷取的“分割點”寫到檔案_partition.lst中,並將它存放到分布式緩衝區中。
舉例說明:比如採樣資料為b,abc,abd,bcd,abcd,efg,hii,afd,rrr,mnk經排序後,得到:abc,abcd,abd,afd,b,bcd,efg,hii,mnk,rrr如果reducetask個數為4,則分割點為:abd,bcd,mnk(2)maptask對資料記錄做標記
每個maptask從檔案_partition.lst讀取分割點,並建立trie樹(假設是2-trie,即組織利用前兩個位元組)。
Maptask從split中一條一條讀取資料,並通過trie樹尋找每條記錄所對應的reducetask編號。比如:abg對應第二個reducetask,mnz對應第四個reducetask。
(3)reducetask進行局部排序
每個reducetask進行局部排序,依次輸出結果即可。4、參考資料
(1)hadoop的1TB排序terasort:
http://hi.baidu.com/dtzw/blog/item/cffc8e1830f908b94bedbc12.html(2)Hadoop-0.20.2代碼
(3)http://sortbenchmark.org