本文全部操做均在 linux 環境下進行。javascript
轉載請註明出處。html
"任何可使用JavaScript來編寫的應用,最終會由JavaScript編寫。"前端
做爲一名小前端,我深受 Jeff Atwood 前輩的鼓舞。上面這條定律即是他提出來的。java
最近在學習 Hadoop ,權威指南 中介紹到了 Hadoop Streaming,說 Hadoop Streaming 是 Hadoop 提供的一個編程工具,它容許用戶使用任何可執行文件或者腳本文件做爲 Mapper 和 Reducer 。書中分別介紹瞭如何使用 Ruby 和 Python 結合 Hadoop Streaming 進行開發。沒有 JS,不開心。咱們 JS 這麼強大,必定也能夠。。。node
咱們先來分析 Hadoop Streaming 的原理,以下:
mapper 和 reducer 會從標準輸入中讀取用戶數據,一行一行處理後發送給標準輸出。Streaming 工具會建立 MapReduce 做業,發送給各個 TaskTracker,同時監控整個做業的執行過程。linux
分析完原理以後咱們知道了只需構造 mapper 和 reducer 便可,他們的工做是從標準輸入讀取用戶數據,以行(hang)爲單位處理完成後發送到標準輸出。web
JavaScript 如何從標準輸入輸出讀寫數據呢?別擔憂,咱們有 NodeJS。
準備好 JavaScript 的運行環境以後開始搭建 Hadoop 的運行環境,參考 Hadoop: 單節點集羣配置。編程
先貼目錄結構:api
$ find . . ./map ./reduce ./wordcount.txt
map
中的代碼以下:bash
#!/usr/bin/env node // 引入readline模塊 const readline = require('readline') // 建立readline接口實例 const rl = readline.createInterface({ input:process.stdin, output:process.stdout }) rl.on('line', line => { // 分離每一行的單詞 line.split(' ').map((word) => { // 將單詞以以下格式寫入標準輸出 console.log(`${word}\t1`) }) }) rl.on("close", () => { process.exit(0) })
reduce
中的代碼以下:
#!/usr/bin/env node const readline = require('readline') const rl = readline.createInterface({ input:process.stdin, output:process.stdout, terminal: false }) // 存儲鍵值對 <String, Number> let words = new Map() rl.on('line', line => { // 解構賦值 const [word, count] = line.split('\t') // 若是 Map 中沒有該單詞,則將該單詞放入 Map ,即第一次添加 if (!words.has(word)) { words.set(word, parseInt(count)) } else { // 若是該單詞已存在,則將該單詞對應的 count 加 1 words.set(word, words.get(word) + 1) } }) rl.on("close", () => { words.forEach((v, k) => { // 將統計結果寫入標準輸出 console.log(`${k}\t${v}`) }) process.exit(0) })
wordcount.txt
中的內容以下:
JS Java JS Python JS Hadoop
目前 map 和 reduce 這兩個程序還沒法運行,須要加可執行權限,方法以下:
$ chmod +x map reduce
如今能夠在終端測試一下程序是否能正確執行:
$ cat wordcount.txt | ./map | ./reduce JS 3 Java 1 Python 1 Hadoop 1
能夠看到,已經正確統計出了詞頻。
接下來只需把做業提交給 Hadoop ,讓它去執行就能夠了。
此時要確保 Hadoop 正常運行
在 HDFS 中建立目錄:
$ hdfs dfs -mkdir input
將待處理文件上傳至 HDFS:
$ hdfs dfs -put wordcount.txt input
此時能夠經過 web 接口查看文件是否正確上傳:
向 Hadoop 提交做業
$ hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-2.7.3.jar \ > -input input/wordcount.txt \ > -output output \ > -mapper map \ > -reducer reduce
檢查計算結果:
$ hdfs dfs -cat output/* Hadoop 1 JS 3 Java 1 Python 1
能夠看到與以前的結果一致。
解釋一下 Hadoop Streaming 的幾個參數:
-input:輸入文件路徑
-output:輸出文件路徑
-mapper:用戶本身寫的 mapper 程序,能夠是可執行文件或者腳本
-reducer:用戶本身寫的 reducer 程序,能夠是可執行文件或者腳本
Hadoop Streaming 編程
Node.js 命令行程序開發教程
Readline | Node.js v7.7.0 Documentation