這裡示範如何在 Ubuntu Linux 的環境中,架設單節點 Hadoop 分散式運算的大資料分析測試環境。
Apache Hadoop 是一個分散式計算的架構,可用於巨量資料(big data)的處理與分析,其原理是利用多台電腦組合成為大型的 Hadoop 叢集電腦,以特殊的 HDFS 檔案系統讓大量的資料分散儲存於各個節點中,而在計算與分析資料時,則是使用 MapReduce 等演算法將計算工作分散在各個節點中平行處理,可用於 PB 級以上的資料儲存與分析。
由於 Hadoop 分散式計算的架構比一般程式更複雜,所以通常在程式的開發與測試階段都會使用單節點的 Hadoop 環境,不管是設備架設與程式除錯都比較方便,以下是使用 Ubuntu Linux 系統架設 Hadoop 單節點測試環境的步驟。
Java 開發與執行環境
安裝 Java 的開發與執行環境,安裝流程請參考 Ubuntu Linux 安裝 Oracle 或 OpenJDK 的 Java JRE 與 JDK 步驟教學。
安裝好之後,確認一下 java
是否正常。
java -version
java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
安裝 Hadoop
安裝 Hadoop 前要決定執行 Hadoop 用的帳號,如果是開發程式用的 Hadoop 測試環境,就使用一般的 Linux 使用者帳號即可。
從 Hadoop 的官方網站下載 Hadoop:
wget ftp://ftp.twaren.net/Unix/Web/apache/hadoop/common/hadoop-2.7.3/hadoop-2.7.3.tar.gz
解壓縮後,將 Hadoop 的目錄放置在要安裝的位置:
tar zxvf hadoop-2.7.3.tar.gz
sudo mv hadoop-2.7.3 /opt/
設定 Hadoop 用的 Java
Hadoop 執行時會讀取 JAVA_HOME
環境變數來取得 Java 的執行環境,請先檢查一下自己的 JAVA_HOME
是否有設定好:
echo $JAVA_HOME
/usr/lib/jvm/java-8-oracle
若沒有設定好,可以在自己的 ~/.bash_profile
或 ~/.bashrc
中加入類似這樣的設定:
export JAVA_HOME="/usr/lib/jvm/java-8-oracle"
讓自己的帳號登入系統時就自動設定好 JAVA_HOME
環境變數。
另外一種設定方式是編輯 Hadoop 目錄下 etc/hadoop/hadoop-env.sh
這個 Hadoop 設定檔,找到其中的 JAVA_HOME
設定:
# The java implementation to use. export JAVA_HOME=${JAVA_HOME}
將 JAVA_HOME
替換為自己的 Java 安裝路徑即可。
設定 PATH
環境變數
將 Hadoop 的執行檔加入自己的 PATH
環境變數中,這樣在執行 Hadoop 時會比較方便。在 ~/.bashrc
中加入:
export HADOOP_HOME=/opt/hadoop-2.7.3 export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
直接載入 ~/.bashrc
的設定並測試執行 hadoop
指令:
source ~/.bashrc hadoop version
Hadoop 2.7.3 Subversion https://git-wip-us.apache.org/repos/asf/hadoop.git -r baa91f7c6bc9cb92be5982de4719c1c8af91ccff Compiled by root on 2016-08-18T01:41Z Compiled with protoc 2.5.0 From source with checksum 2e4ce5f957ea4db193bce3734ff29ff4 This command was run using /opt/hadoop-2.7.3/share/hadoop/common/hadoop-common-2.7.3.jar
Hadoop 單機模式測試
Hadoop 有幾種執行模式,分別適用於不同的情況:
- 單機模式(tandalone mode)
- 所有的 Hadoop 程式都在單一的 JVM 中執行,沒有啟動 Hadoop daemons,這樣測試與除錯都會比較容易(尤其是 MapReduce 類型的程式),很適合用於程式開發階段。
- 模擬分散模式(pseudo-distributed mode)
- 使用單一台機器,多個 Java 行程來執行 Hadoop 程式,模擬分散式架構。
- 完整分散模式(fully-distributed mode)
- 使用多台機器平行執行 Hadoop 程式,用於正式的 Hadoop 叢集電腦。
Hadoop 在安裝好的時候,預設的設定就是單機模式,所以如果您需要的 Hadoop 環境就是單機模式,那就不需要再去更動它的設定檔了。
我們可以使用 Hadoop 內建的範例測試一下 Hadoop 是否可以正常執行,首先複製一些 Hadoop 的 XML 設定檔作為測試用的文字資料:
cp -r $HADOOP_HOME/etc/hadoop input
執行內建的 MapReduce 範例程式,這個範例會將 input
中的檔案以 MapReduce 的方式,用正規表達式(regular expression)搜尋,並將結果儲存於 output
目錄中:
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar grep input output 'dfs[a-z.]+'
在執行這個 Hadoop 範例程式時,會有相當多的訊息,執行完畢之後,會產生一個 output
目錄:
ls output/
part-r-00000 _SUCCESS
若程式執行成功的話,在 output
目錄中會建立一個 _SUCCESS
檔案,而 part-r-00000
就是執行結果:
cat output/part-r-00000
6 dfs.audit.logger 4 dfs.class 3 dfs.server.namenode. 2 dfs.period 2 dfs.audit.log.maxfilesize 2 dfs.audit.log.maxbackupindex 1 dfsmetrics.log 1 dfsadmin 1 dfs.servers 1 dfs.replication 1 dfs.file
設定 Hadoop 模擬分散模式
Hadoop 的模擬分散執行模式可以讓單一台機器執行多個 Java 行程,模擬叢集電腦的執行狀況,以下是將 Hadoop 設定為模擬分散模式的設定方式。
Hadoop 主要的設定都是寫在 etc/hadoop
目錄中的 XML 檔裡面,以下是比較重要的 XML 設定檔:
core-site.xml
:Hadoop 基本設定檔。hdfs-site.xml
:HDFS 設定檔。mapred-site.xml
:MapReduce 設定檔。yarn-site.xml
:YARN 設定檔。
更改 core-site.xml
設定檔內容:
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> </configuration>
更改 hdfs-site.xml
設定檔內容:
<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> </configuration>
設定 SSH 金鑰認證登入
安裝 ssh 伺服器:
sudo apt-get install openssh-server
設定 ssh 金鑰認證登入:
ssh-keygen cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys chmod 0600 ~/.ssh/authorized_keys
檢查 ssh 登入是否需要密碼:
ssh localhost
將資料放入 HDFS
HDFS 檔案系統在第一次使用前,要先進行格式化的動作:
hdfs namenode -format
啟動 NameNode 與 DataNode daemon:
start-dfs.sh
打開 NameNode 的網頁介面網址 http://localhost:50070/
,看看網頁是否可以正常顯示:
建立使用者用的目錄:
hdfs dfs -mkdir -p /user/gtwang
將資料放進 HDFS 中:
hdfs dfs -put $HADOOP_HOME/etc/hadoop input
查看一下資料:
hdfs dfs -ls input
執行 MapReduce 測試程式
執行 MapReduce 程式:
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar grep input output 'dfs[a-z.]+'
將資料取回並查看結果:
hdfs dfs -get output output cat output/*
6 dfs.audit.logger 4 dfs.class 3 dfs.server.namenode. 2 dfs.period 2 dfs.audit.log.maxfilesize 2 dfs.audit.log.maxbackupindex 1 dfsmetrics.log 1 dfsadmin 1 dfs.servers 1 dfs.file
若不想取回資料,也可以直接使用以下的指令查看結果:
hdfs dfs -cat output/*
執行完畢之後,關閉 daemons:
stop-dfs.sh
補充資料
如果在執行時出現類似這樣的錯誤訊息:
17/02/21 10:32:48 WARN hdfs.DFSClient: Caught exception java.lang.InterruptedException at java.lang.Object.wait(Native Method) at java.lang.Thread.join(Thread.java:1249) at java.lang.Thread.join(Thread.java:1323) at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.closeResponder(DFSOutputStream.java:609) at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.closeInternal(DFSOutputStream.java:577) at org.apache.hadoop.hdfs.DFSOutputStream$DataStreamer.run(DFSOutputStream.java:573)
這個看起來是 Hadoop 的 bug,暫時可以忽略它。
參考資料:Apache Hadoop、台大計資中心、DigitalOcean、BogoToBogo、iThome