如何使用hadoop對海量資料進行統計並排序

2021-09-01 20:37:40 字數 3815 閱讀 2538

[b][color=green][size=x-large]不得不說,hadoop確實是處理海量離線資料的利器,當然,凡是乙個東西有優點必定也有缺點,hadoop的缺點也很多,比如對流式計算,實時計算,dag具有依賴關係的計算,支援都不友好,所以,由此誕生了很多新的分布式計算框架,storm,spark,tez,impala,drill,等等,他們都是針對特定問題提出一種解決方案,新框架的的興起,並不意味者他們就可以替代hadoop,一手獨大,hdfs和mapreduce依舊是很優秀的,特別是對離線海量資料的處理。[/size][/color][/b]

散仙,今天的這個例子的場景要對幾億的單詞或短語做統計和並按詞頻排序,當然這些需求都是類似wordcount問題,如果你把hadoop自帶的wordcount的例子,給搞懂了,基本上做一些ip,熱詞的統計與分析就很很容易了,wordcount問題,確實是乙個非常具有代表性的例子。

[/size][/color][/b]

[b][color=green][size=x-large]下面進入正題,先來分析下散仙這個例子的需求,總共需要二步來完成,第一步就是對短語的統計,第二步就是對結果集的排序。所以如果使用mapreduce來完成的話,就得需要2個作業來完成這件事情,第乙個作業來統計詞頻,第二個來負責進行排序,當然這兩者之間是有依賴關係的,第二個作業的執行,需要依賴第乙個作業的結果,這就是典型的m,r,r的問題並且作業之間具有依賴關係,這種問題使用mapreduce來完成,效率可能有點低,如果使用支援dag作業的tez來做這件事情,那麼就很簡單了。不過本篇散仙,要演示的例子還是基於mapreduce來完成的,有興趣的朋友,可以研究一下使用tez。[/size][/color][/b]

[b][color=green][size=x-large]對於第乙個作業,我們只需要改寫wordcount的例子,即可,因為散仙的需求裡面涉及短語的統計,所以定義的格式為,短語和短語之間使用分號隔開,(預設的格式是按單詞統計的,以空格為分割符)在map時只需要,按分號打散成陣列,進行處理即可,測試的資料內容如下:[/size][/color][/b]

[img]

[img]

[b][color=olive][size=x-large]map裡面的核心**如下:[/size][/color][/b]

/**

* 統計詞頻的map端

* **

* * **/

public void map(object key, text value, context context

) throws ioexception, interruptedexception

}}

[b][color=olive][size=x-large]reduce端的核心**如下:[/size][/color][/b]

/**

* reduce端的

* **

* **/

public void reduce(text key, iterablevalues,

context context

) throws ioexception, interruptedexception

result.set(sum);

context.write(new text(key.tostring()+"::"), result);//為方便短語排序,以雙冒號分隔符間隔

}}

[b][color=olive][size=x-large]main函式裡面的**如下:[/size][/color][/b]

[b][color=olive][size=x-large]執行結果,如下所示:[/size][/color][/b]

a good student::	1

good student:: 3

patient:: 2

patient a:: 1

[b][color=olive][size=x-large]下面,散仙來分析下排序作業的**,如上圖所示hadoop預設的排序,是基於key排序的,如果是字元型別的則基於字典表排序,如果是數值型別的則基於數字大小排序,兩種方式都是按預設的公升序排列的,如果想要降序輸出,就需要我們自己寫個排序元件了,散仙會在下面的**給出例子,因為我們是要基於詞頻排序的,所以需要反轉k,v來實現對詞頻的排序,map端**如下:[/size][/color][/b]

/**

* 排序作業

* map的實現

* * **/

@override

protected void map(longwritable key, text value,context context)throws ioexception, interruptedexception

[b][color=olive][size=x-large]reduce端**如下:[/size][/color][/b]

/***

* * 排序作業的

* reduce**

* **/

@override

protected void reduce(intwritable arg0, iterablearg1, context arg2)

throws ioexception, interruptedexception

}

[b][color=olive][size=x-large]下面,我們再來看下排序元件的**:[/size]

[/color][/b]

/***

* 按詞頻降序排序

* 的類

* * **/

public static class descsort extends writablecomparator

@override

public int compare(byte arg0, int arg1, int arg2, byte arg3,

int arg4, int arg5)

@override

public int compare(object a, object b)

}

[b][color=olive][size=x-large]main方法裡面的實現**如下所示:[/size]

[/color][/b]

[b][color=olive][size=x-large]輸出結果,如下所示:[/size][/color][/b]

good student	3

patient 2

a good student 1

patient a 1

[b][color=olive][size=x-large]至此,我們可以成功實現,統計並排序的業務,當然這種型別的需求非常多而且常見,如對某個海量日誌ip的分析,散仙上面的例子使用的只是測試的資料,而真實資料是對幾億或幾十億的短語構建語料庫使用,配置集群方面,可以根據自己的需求,配置集群的節點個數以及map,reduce的個數,而**,只需要我們寫好,提交給hadoop集群執行即可。[/size][/color][/b]

[b][color=olive][size=x-large]最後在簡單總結一下,資料處理過程中,格式是需要提前定製好的,也就是說你得很清楚的你的格式代表什麼意思,另外一點,關於hadoop的中文編碼問題,這個是內部固定的utf-8格式,如果你是gbk的檔案編碼,則需要自己單獨在map或reduce過程中處理一下,否則輸出的結果可能是亂碼,最好的方法就是統一成utf-8格式,否則,很容易出現一些編碼問題的。[/size][/color][/b]

ORACLE如何處理海量資料

當前資料存在的問題 一 資料量過大,資料中什麼情況都可能存在。如果說有10條資料,那麼大不了每條去逐一檢查,如果資料上到千萬級別,甚至過億,那不是手工能解決的了,必須通過工具或者程式進行處理,尤其海量的資料 二 軟硬體要求高,系統資源佔用率高。對海量的資料進行處理,除了好的方法,最重要的就是合理使用...

redis 之如何訪問海量資料。

如何訪問redis中海量資料,服務不會受影響?我們知道使用keys可以找出想要的結果,但是redis有乙個很關鍵的特性 單執行緒。keys演算法是遍歷演算法,複雜度是0 n 資料越多時間越高。keys指令會順序執行,這將導致執行緒阻塞一段時間,直到執行完畢。想象一下如果一次找出幾百萬以上的資料,執行...

對海量資料處理步驟及策略

第一優化你的sql和索引 第二加快取,memcached,redis 第三以上都做了後,還是慢,就做主從複製或主主複製,讀寫分離,可以在應用層做,效率高,也可以用三方工具,第三方工具推薦360的atlas,其它的要麼效率不高,要麼沒人維護 第四如果以上都做了還是慢,不要想著去做切分,mysql自帶分...