Hadoop:使用 JavaScript 構建

說明

  1. 本文全部操做均在 linux 環境下進行。javascript

  2. 轉載請註明出處。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

此時要確保 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 的幾個參數:

  1. -input:輸入文件路徑

  2. -output:輸出文件路徑

  3. -mapper:用戶本身寫的 mapper 程序,能夠是可執行文件或者腳本

  4. -reducer:用戶本身寫的 reducer 程序,能夠是可執行文件或者腳本

參考資料

Hadoop Streaming 編程
Node.js 命令行程序開發教程
Readline | Node.js v7.7.0 Documentation

相關文章
相關標籤/搜索