隨著數據規模的增長,Apache Hadoop 已成為大數據處理的核心框架。然而,傳統 Hadoop 叢集部署流程繁瑣且環境依賴性高,構成入門障礙。容器化技術,特別是 Docker,為此提供了輕量化、可移植且具備一致性的解決方案。本文聚焦於整合 Docker 與 Hadoop,利用標準化容器鏡像快速建構一個功能完整的單節點 Hadoop 環境。我們將以經典的 MapReduce 運算模型為例,實際操作詞頻統計(Word Count)應用,藉此闡明 Hadoop 在分散式運算與資料處理上的核心機制,展示容器化部署如何簡化開發與測試流程。

Hadoop Docker 部署與 MapReduce 準備

本節將引導讀者完成 Hadoop Docker 鏡像的下載、容器的啟動,以及為 MapReduce 的 Word Count 應用準備輸入文件。

下載並啟動 Hadoop Docker 鏡像

  1. 下載 Hadoop Docker 鏡像: 我們將使用 sequenceiq/hadoop-docker 這個鏡像,並指定版本標籤 2.7.0。如果存在更新的版本,可根據需要替換標籤。

    sudo docker pull sequenceiq/hadoop-docker:2.7.0
    

    此命令會從 Docker Hub 下載指定的 Hadoop 鏡像。

  2. 啟動 Hadoop 容器: 執行以下命令來啟動一個 Hadoop Docker 容器。這個容器將在後台運行,並初始化 HDFS(NameNode 和 DataNode)以及 YARN(ResourceManager 和 NodeManager)組件。

    sudo docker run -d --name hadoop sequenceiq/hadoop-docker:2.7.0
    
    • -d:表示以分離模式(後台)運行容器。
    • --name hadoop:為容器指定名稱為 hadoop
    • sequenceiq/hadoop-docker:2.7.0:指定要使用的 Docker 鏡像及其標籤。
  3. 驗證容器運行狀態: 使用 docker ps 命令可以查看當前正在運行的 Docker 容器。您應該能看到名為 hadoop 的容器正在運行。

進入 Hadoop 交互式終端

為了與 Hadoop 集群進行交互,需要進入容器的 Shell 環境。

  1. 啟動交互式終端: 使用 docker exec 命令進入正在運行的 Hadoop 容器。

    sudo docker exec -it hadoop bash
    
    • -it:結合了 -i (交互式) 和 -t (分配偽終端),用於啟動一個交互式 Shell 會話。
    • hadoop:容器的名稱。您也可以使用容器 ID 替換。

    成功執行後,您將看到類似 bash-4.1# 的提示符,表示您已進入 Hadoop 容器的 Shell。

  2. 前台模式啟動(可選): 如果您希望在啟動容器時直接進入交互式終端,可以省略 -d 參數,並使用 -it 參數。同時,可能需要指定啟動腳本。

    sudo docker run -it --name hadoop sequenceiq/hadoop-docker:2.7.0 /etc/bootstrap.sh -bash
    

    這種方式會直接將 Hadoop 組件的啟動日誌輸出到終端,並將您連接到其標準輸入、輸出和錯誤流。

為 MapReduce 準備輸入文件

本節將創建一個用於 MapReduce Word Count 應用程序的輸入文件。

  1. 切換至 Hadoop 前綴目錄: 在交互式終端中,首先需要將當前目錄更改為 Hadoop 的安裝前綴目錄。

    cd $HADOOP_PREFIX
    

    $HADOOP_PREFIX 通常指向 Hadoop 的安裝路徑。

  2. 在 HDFS 中創建輸入目錄: 使用 Hadoop 的分布式文件系統命令 (hdfs dfs) 在 HDFS 中創建一個名為 /input 的目錄,用於存放輸入文件。

    bin/hdfs dfs -mkdir /input
    
  3. 設置目錄權限: 為了確保所有用戶都能訪問此目錄中的文件,將其權限設置為全局可讀寫(777)。

    bin/hdfs dfs -chmod -R 777 /input
    

    這些命令都應在 Hadoop 容器的交互式終端中執行。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

object "使用者" as User
object "Docker CLI" as DockerCLI
object "Host OS" as HostOS
object "Docker Daemon" as DockerDaemon
object "Couchbase Container (couchbasedb)" as CouchbaseContainer
object "Hadoop Docker Image (sequenceiq/hadoop-docker:2.7.0)" as HadoopImage
object "Hadoop Container (hadoop)" as HadoopContainer
object "Hadoop Shell" as HadoopShell
object "HDFS CLI" as HDFSCLI

partition "Hadoop 鏡像與容器啟動" {
  User --> HostOS : 執行 sudo docker pull sequenceiq/hadoop-docker:2.7.0
  HostOS --> DockerDaemon : 下載鏡像
  DockerDaemon --> User : 鏡像下載完成
  User --> HostOS : 執行 sudo docker run -d --name hadoop sequenceiq/hadoop-docker:2.7.0
  HostOS --> DockerDaemon : 創建並啟動容器
  DockerDaemon --> HadoopContainer : 啟動 HDFS (NameNode, DataNode) & YARN (ResourceManager, NodeManager)
  User --> HostOS : 執行 sudo docker ps
  HostOS --> DockerDaemon : 請求運行中容器列表
  DockerDaemon --> User : 列出 hadoop 容器
}

partition "交互式終端與 HDFS 操作" {
  User --> DockerCLI : 執行 sudo docker exec -it hadoop bash
  DockerCLI --> HadoopContainer : 啟動容器內 shell
  HadoopContainer --> HadoopShell : 提供終端接口
  User --> HadoopShell : 執行 cd $HADOOP_PREFIX
  User --> HadoopShell : 執行 bin/hdfs dfs -mkdir /input
  HadoopShell --> HDFSCLI : 請求創建目錄
  HDFSCLI --> HadoopContainer : 在 HDFS 中創建 /input 目錄
  User --> HadoopShell : 執行 bin/hdfs dfs -chmod -R 777 /input
  HadoopShell --> HDFSCLI : 請求設置權限
  HDFSCLI --> HadoopContainer : 為 /input 目錄設置全局權限
}

@enduml

看圖說話:

此圖示詳細闡述了部署 Apache Hadoop 的關鍵步驟。首先,它展示了如何通過 docker pull 命令獲取 sequenceiq/hadoop-docker:2.7.0 鏡像,隨後使用 docker run -d 命令在後台啟動 Hadoop 容器,該容器集成了 HDFS 和 YARN 組件。接著,圖示描繪了如何通過 docker exec -it 命令進入 Hadoop 容器的交互式 Shell。在 Shell 環境中,使用者執行了 cd $HADOOP_PREFIX 命令切換到 Hadoop 的安裝目錄,然後使用 bin/hdfs dfs -mkdir /inputbin/hdfs dfs -chmod -R 777 /input 命令在 HDFS 中創建了一個名為 /input 的目錄,並設置了全局寫入權限。這為後續的 MapReduce 應用準備了必要的輸入文件存放空間。

準備 MapReduce 輸入數據與執行 Word Count 應用

本節將詳細說明如何創建 MapReduce 應用所需的輸入文件,並在 Hadoop 環境中執行一個經典的 Word Count 任務。

創建 MapReduce 輸入文件

為了運行 Word Count 應用,我們需要在 HDFS 中準備包含文本內容的輸入文件。

  1. 創建 input1.txt 文件

    • 在 Hadoop 容器的交互式終端中,使用 vi 編輯器創建一個名為 input1.txt 的文本文件。
      vi input1.txt
      
    • 在編輯器中輸入以下兩行文本:
      Hello World Application for Apache Hadoop
      Hello World and Hello Apache Hadoop
      
    • 使用 :wq 命令保存並退出 vi 編輯器。
  2. input1.txt 上傳至 HDFS: 使用 hdfs dfs -put 命令將本地創建的 input1.txt 文件複製到 HDFS 的 /input 目錄下。

    bin/hdfs dfs -put input1.txt /input
    
  3. 創建 input2.txt 文件

    • 同樣地,使用 vi 編輯器創建另一個文本文件 input2.txt
      vi input2.txt
      
    • 輸入以下文本內容:
      Hello World
      Hello Apache Hadoop
      
    • 使用 :wq 命令保存並退出。
  4. input2.txt 上傳至 HDFS: 將 input2.txt 文件複製到 HDFS 的 /input 目錄。

    bin/hdfs dfs -put input2.txt /input
    
  5. 驗證 HDFS 中的輸入文件: 執行 hdfs dfs -ls /input 命令,列出 /input 目錄下的所有文件,確認 input1.txtinput2.txt 已成功上傳。

執行 MapReduce Word Count 應用

現在,我們將利用 Hadoop 自帶的 MapReduce 示例來執行 Word Count 任務。

  1. 調用 MapReduce 任務: 在交互式終端中,執行以下 Hadoop 命令來運行 Word Count 應用。該應用程序包含在 hadoop-mapreduce-examples-2.7.0.jar 文件中,我們將使用 wordcount 作為參數。

    bin/hadoop jar $HADOOP_PREFIX/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.0.jar wordcount /input /output
    
    • $HADOOP_PREFIX/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.0.jar:指定包含 Word Count 應用程序的 JAR 文件路徑。
    • wordcount:指定要執行的 MapReduce 應用程序類型。
    • /input:指定輸入數據所在的 HDFS 目錄。
    • /output:指定 MapReduce 任務的輸出結果將被寫入的 HDFS 目錄。注意:此目錄必須在運行前不存在
  2. 監控 MapReduce 作業: 執行上述命令後,Hadoop 將使用 YARN 框架啟動一個 MapReduce 作業。您可以在終端看到作業啟動的日誌信息,包括連接到 ResourceManager、輸入路徑總數、數據分割信息以及作業提交的詳細記錄。

  3. 查看作業輸出: 當 MapReduce 作業成功完成後,其輸出結果(每個單詞及其出現的次數)將被寫入 HDFS 的 /output 目錄。您可以使用 hdfs dfs -ls /output 來查看輸出文件,並通過 hdfs dfs -cat /output/<part-file> 命令查看具體的計數結果。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

object "使用者" as User
object "Hadoop Shell" as HadoopShell
object "HDFS CLI" as HDFSCLI
object "Hadoop Container (hadoop)" as HadoopContainer
object "HDFS" as HDFS
object "YARN ResourceManager" as YARN_RM
object "MapReduce Job" as MR_Job
object "Map Task" as MapTask
object "Reduce Task" as ReduceTask

partition "準備輸入文件" {
  User --> HadoopShell : 執行 vi input1.txt
  HadoopShell --> User : 啟動 vi 編輯器
  User --> HadoopShell : 輸入文本並保存 (:wq)
  User --> HadoopShell : 執行 bin/hdfs dfs -put input1.txt /input
  HadoopShell --> HDFSCLI : 上傳文件到 HDFS
  HDFS --> HadoopContainer : 存儲 input1.txt
  User --> HadoopShell : 執行 vi input2.txt
  HadoopShell --> User : 啟動 vi 編輯器
  User --> HadoopShell : 輸入文本並保存 (:wq)
  User --> HadoopShell : 執行 bin/hdfs dfs -put input2.txt /input
  HadoopShell --> HDFSCLI : 上傳文件到 HDFS
  HDFS --> HadoopContainer : 存儲 input2.txt
  User --> HadoopShell : 執行 bin/hdfs dfs -ls /input
  HadoopShell --> HDFSCLI : 列出 HDFS 目錄內容
  HDFSCLI --> User : 顯示 input1.txt, input2.txt
}

partition "執行 MapReduce Word Count" {
  User --> HadoopShell : 執行 bin/hadoop jar ... wordcount /input /output
  HadoopShell --> YARN_RM : 提交 MapReduce 作業請求
  YARN_RM --> MR_Job : 分配資源並啟動作業
  MR_Job --> MapTask : 執行 Map 階段 (讀取 /input)
  MapTask --> MR_Job : 產生中間鍵值對 (word, 1)
  MR_Job --> ReduceTask : 執行 Reduce 階段 (聚合中間鍵值對)
  ReduceTask --> MR_Job : 產生最終結果 (word, count)
  MR_Job --> HDFS : 寫入 /output 目錄
  HDFS --> HadoopContainer : 存儲輸出結果
  YARN_RM --> User : 顯示作業完成日誌
}

@enduml

看圖說話:

此圖示詳細展示了為 MapReduce 應用準備輸入數據以及執行 Word Count 作業的完整流程。首先,它描繪了使用者在 Hadoop 容器的 Shell 環境中,使用 vi 編輯器創建了兩個文本文件 input1.txtinput2.txt,並分別向其中填入了示例文本。接著,通過 bin/hdfs dfs -put 命令將這兩個文件成功上傳至 HDFS 的 /input 目錄,並通過 bin/hdfs dfs -ls /input 命令進行了驗證。隨後,圖示重點展示了如何調用 bin/hadoop jar ... wordcount /input /output 命令來啟動 Word Count MapReduce 作業。這個過程包括將作業提交給 YARN ResourceManager,由 YARN 分配資源啟動 Map 和 Reduce 任務,對 /input 目錄下的數據進行詞頻統計,最終將結果寫入 HDFS 的 /output 目錄。圖示清晰地呈現了數據流動和處理過程,從文件的創建到最終結果的生成。

檢視此技術實踐路徑在高效率學習與專案原型開發上的效果,其核心價值不僅在於完成一次 Word Count 任務。它透過 Docker 容器化技術,將傳統 Hadoop 部署中繁瑣的環境配置與依賴問題大幅簡化,從而顯著降低了踏入大數據領域的初始門檻。這不僅是技術操作的便捷化,更是學習模式的革新——讓開發者能將寶貴的時間與心力,從環境搏鬥轉向對 MapReduce 運算思維與 HDFS 分散式儲存原理的深度理解。

然而,也需清晰認知,此單節點容器化環境主要適用於學習與功能驗證,與真實生產環境中的多節點叢集管理、效能調校與高可用性挑戰,仍存在巨大鴻溝。展望未來,容器化部署將不僅限於 Hadoop,而是貫穿整個數據技術棧的標準實踐。掌握將複雜分散式系統「輕量化」、「可攜化」的能力,將成為數據工程師與架構師不可或缺的核心競爭力,加速從概念到價值的轉化週期。

玄貓認為,將攻克複雜技術的初始門檻視為首要優化標的,正是現代技術人才實現高效學習與持續迭代的關鍵心法。此番實踐,即是該心法的絕佳體現。