趣味集算:wordcount

WordCount
WordCount 差很少是最經常使用的分佈式系統練習程序了,Hadoop 就常常用這個當例子。咱們來看用集算器怎麼作 wordcount。程序員

先從單線程開始。

例如,D:\files\novel 目錄中,有一些小說文檔,如今,須要統計這些小說中哪些單詞最爲經常使用:服務器

wordcount-1

在集算器中,若是不嫌寫得長,只要一句代碼就能夠搞定了:多線程

A
1 =directory@p(「D:/files/novel」).(file().read().words().groups(lower():Word;count(~):Count)).merge(Word).groups@o(Word;sum(Count):Count).sort@z(Count)

怎麼樣,是否是超級簡單?計算後,A1 中獲得的結果以下:分佈式

wordcount-2

不過,這句確實有點長,爲了便於理解,咱們能夠把它拆成多步來執行:oop

A B C
1 =directory@p(「D:/files/novel」) [] =now()
2 for A1 =file(A2).read().words()
3 =B2.groups(lower():Word;count():Count)
4 >B1=B1 [B3]
5 =B1.merge(Word) =A5.groups@o(Word;sum(Count):Count).sort@z(Count) =interval@ms(C1,now())

在 A1 中,列出目錄中的各個文件:性能

wordcount-3

第 2~4 行循環統計每一個文件中的單詞。B2 中讀取文件中的文本並拆分紅單詞:spa

wordcount-4

B3 中統計出當前文檔中每一個單詞出現的次數,統計時將單詞轉換爲小寫字母,以免大小寫變化的影響。結果將按照單詞的字典順序排列:線程

wordcount-5

在每一個文檔統計完成後,在 B4 中將結果記錄到 B1 中,全部文檔統計後,B1 中結果以下:進程

wordcount-6

在 A5 中,將這些結果按照每一個單詞歸併起來,結果以下:ip

wordcount-7

B5 中,將歸併後的統計結果按每一個單詞聚合計算,再將結果按 Count 降序排列,能夠獲得和前面單條語句時相同的結果:

wordcount-8

在 C1 和 C5 中,經過記錄執行開始先後的時刻,估算出計算所需的毫秒數以下:

wordcount-9

可見,執行效率仍是很是高的。

搞完單線程,咱們再來試試多線程的搞法。

並行計算會不會麻煩不少啊?看看代碼吧:

A B C
1 =directory@p(「D:/files/novel」) =now()
2 fork A1 =file(A2).read().words()
3 =B2.groups(lower(~):Word;count(~):Count)
4 =A2.merge(Word) =A4.groups@o(Word;sum(Count):Count).sort@z(Count) =interval@ms(C1,now())

嗯,好象差很少嘛,就是把 A2 的那個 for 換成了 fork,其它代碼基本沒什麼變化。看看 C4 中的計時狀況

wordcount-10

果真快了,並行真地起了做用(俺的筆記本只有雙核,有這個性能提升也就差很少了)。

這個 fork 語句就會自動把原本單線程串行執行的 for 循環變成多線程並行循環計算,程序員徹底不用操心線程管理的事,是否是很簡單?

搞完多線程,現來搞集羣

懶得真搞多個服務器來,就用一臺機器啓動多個進程模擬一下吧。在集算器安裝目錄的 esProc\bin 路徑下,能夠找到 esprocs.exe 文件,能夠直接運行它來啓動或配置服務器:

wordcount-11

在首次用 Start 按鍵啓動服務器以前,能夠先點擊 Config 配置並行服務器的相關信息,如在 Unit 頁面中配置本機中所要啓動的服務器 ip 及端口:

wordcount-12

配置完成後,就能夠回到服務器主窗口啓動服務器。重複執行 esprocs.exe 能夠再啓動兩個服務器,這 3 個服務器將依次使用配置中設置的 ip 和端口。這樣單機上的服務器集羣就準備完畢了。

下面準備統計 4 個路徑中全部文檔的單詞,因爲這裏使用單機模擬服務器集羣的,因此每一個服務器都是共用相同路徑的,若是是遠程服務器,設定時路徑可能也會有所差別。

A B C
1 [192.168.10.229:4001,192.168.10.229:4004,192.168.10.229:4007] [D:/files/novel1,D:/files/novel2, D:/files/novel3,D:/files/novel4]
2 fork B1;A1 =directory@p(A2)
3 fork B2 =file(B3).read().words()
4 =C3.groups(lower():Word;count():Count)
5 return B3.merge(Word)
6 =A2.merge(Word) =A6.groups@o(Word;sum(Count):Count).sort@z(Count)

在計算時,用 4 個文件路徑做爲參數,須要執行 4 個子任務分別計算某個路徑中文件的單詞數。只須要在 fork 後面加上各個服務器節點的地址,這些子任務就能夠由集算器自動分派給服務器節點去計算並將結果彙總,程序員根本不用操心這些小問題。最後在 B6 中計算出結果以下:

wordcount-13

從各個服務器窗口中,能夠看到集羣計算任務的分配執行狀況:

wordcount-14

wordcount-15

wordcount-16

怎麼樣?很簡單吧,Hadoop 還沒搭建起來的時間,咱已經把活幹完了。

相關文章
相關標籤/搜索