架設 Hadoop對於新手來說,常會遇到很多莫名其妙的問題。這些問題,不外乎是版本不同、環境不同,或是對 Linux指令不熟。傑瑞也是過來人,當初在架設時遇到一些困難,所以想把架設的經驗寫下來,或許對大家有幫助。本文的內容會教大家如何在 Ubuntu上佈署雙節點 Hadoop,並列出一些注意事項供參考。


準備工作

首先,準備兩台安裝好 Ubuntu 14.04的測試機台 (分別稱作 Master與 Slave),並確認網路暢通。可以在自己的實體機架設或利用 Amazon、Google等廠商提供的雲端服務來建立自己的虛擬機器。這裡,我使用 Google Compute Engine提供的服務,在上面建立了兩台 Ubuntu 14.04主機


安裝流程

  • 新增用戶與群組
  • 設定網路
  • 設定SSH連線
  • 安裝JAVA
  • 安裝Hadoop
  • 設定Hadoop

1. 新增用戶與群組

分別在兩台機器中,創建一個新使用者 hadoopuser,歸屬於hadoopgroup這個群組,並設定密碼

$ sudo addgroup hadoop
$ sudo adduser -ingroup hadoop hadoopuser
$ sudo passwd hadoopuser

接著切換到 hadoopuser

$ su - hadoopuser

加入(-)代表切換至 hadoopuser根目錄


2.設定網路

為了方便SSH連線,我們要先設定hostname以及host list。 hostname為主機名稱,也就是terminal下小老鼠(@)右邊顯示的名稱 打開hostname檔案,將一台改為master,另一台改為slave1

$ sudo vim /etc/hostname

改完後請重新啟動電腦,讓設定生效
如果不想重開的話,可以使用hostname指令,做一次性的設定

$ sudo hostname master

hosts檔案放置IP與主機名稱的對應,這裡我填的是內網IP 注意不要把原本的localhost唷

$ sudo vim /etc/hosts
10.240.0.4 master
10.240.0.5 slave1


3.設定SSH連線

master使用ssh並透過金鑰認證,將工作分配給各個slave運算,因此我們要產生一組key,做免密碼SSH登入。 首先,利用Ubuntu的apt-get在兩台電腦安裝SSH (已安裝就可跳過)

$ sudo apt-get install ssh

在Master產生一組ssh key,產生完就會出現一個框框

$ ssh-keygen -t rsa -P ""

將公鑰複製給slave1

$ cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
$ scp -r ~/.ssh slave1:~/

設定完後,用master試試可否連線至slave1,成功的話就會看到@後面變成slave1了

如果無法用scp複製金鑰,有可能系統預設使用金鑰驗證(如下圖),可是我們就是要加入金鑰阿,所以要修該一下/etc/ssh/sshd_config檔案,將密碼驗證開啟。(GCE上的Ubuntu預設是PasswordAuthentication no)

$ sudo vim /etc/ssh/sshd_config

將 PasswordAuthentication改為 yes

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication yes

修改完後,重新啟動ssh服務,再試試看

$ sudo service ssh restart


4.安裝JAVA

在兩台電腦中安裝 java jdk

$ sudo apt-get install openjdk-7-jdk

安裝好後可以查看版本,確認是否有成功安裝

hadoopuser@master:~$ java -version
java version "1.7.0_91"
OpenJDK Runtime Environment (IcedTea 2.6.3) (7u91-2.6.3-0ubuntu0.14.04.1)
OpenJDK 64-Bit Server VM (build 24.91-b01, mixed mode)


5.安裝Hadoop

這邊我裝的是2.6.0版本,因為當時看網路的教學比較多人用這版本,想說有問題比較好解決

先在master執行以下指令上安裝,之後再用scp複製到slave1

$ sudo wget http://ftp.twaren.net/Unix/Web/apache/hadoop/common/hadoop-2.6.0/hadoop-2.6.0.tar.gz
$ sudo tar -zxvf hadoop-2.6.0.tar.gz
$ sudo mv hadoop-2.6.0 /opt/hadoop
$ sudo chown -R hadoopuser:hadoop /opt/hadoop
$ cd ~
$ mkdir hdfs
$ mkdir /home/hadoopuser/hdfs/name
$ mkdir /home/hadoopuser/hdfs/data
$ mkdir /home/hadoopuser/tmp

說明

  • 下載 hadoop 2.6.0版
  • 將hadoop解壓縮,移動到要存放的位置 /opt/hadoop
  • 設定資料夾的擁有者為 hadoopuser
  • 建立一個 hdfs空間(可以自行決定位置),我放在 home/hdfs

6.設定Hadoop

  • 在 .bashrc檔案中加入環境變數,設定hadoop以及java的位置

$ sudo vim ~/.bashrc

# Set HADOOP_HOME
export HADOOP_HOME=/opt/hadoop
# Set JAVA_HOME 
export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
# Add Hadoop bin and sbin directory to PATH
export PATH=$PATH:$HADOOP_HOME/bin;$HADOOP_HOME/sbin
export HADOOP_CLASSPATH=$JAVA_HOME/lib/tools.jar
  • hadoop的兩個檔案(hadoop-env.sh,yarn-env.sh)也要加入java環境變數

$ sudo vim /opt/hadoop/etc/hadoop/hadoop-env.sh
$ sudo vim /opt/hadoop/etc/hadoop/yarn-env.sh

export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
  • 修改core-site.xml

$ sudo vim /opt/hadoop/etc/hadoop/core-site.xml

<property>
   <name>fs.defaultFS</name>
   <value>hdfs://master:9000</value>
</property>
<property>
   <name>io.file.buffer.size</name>
   <value>131072</value>
</property>
<property>
   <name>hadoop.tmp.dir</name>
   <value>/home/hadoopuser/tmp</value>
</property>
<property>
   <name>hadoop.proxyuser.root.hosts</name>
   <value>master</value>
</property>
<property>
   <name>hadoop.proxyuser.root.group</name>
   <value>*</value>
</property>
  • 修改hdfs-site.xml

$ sudo vim /opt/hadoop/etc/hadoop/hdfs-site.xml

<property>
   <name>dfs.namenode.secondary.http-address</name>
   <value>master:9001</value>
</property>
<property>
   <name>dfs.namenode.name.dir</name>
   <value>/home/hadoopuser/hdfs/name</value>
</property>
<property>
   <name>dfs.datanode.data.dir</name>
   <value>/home/hadoopuser/hdfs/data</value>
</property>
<property>
   <name>dfs.replication</name>
   <value>1</value>
</property>
<property>
   <name>dfs.webhdfs.enable</name>
   <value>true</value>
</property>
<property>
   <name>dfs.permissions</name>
   <value>false</value>
</property>
  • 新增並修改mapred-site.xml

hadoop目錄下沒有mapred-site.xml這個檔案,要複製mapred-site.xml.template並把他更名為mapred-site.xml

$ sudo cp /opt/hadoop/etc/hadoop/mapred-site.xml.template /opt/hadoop/etc/hadoop/mapred-site.xml
$ sudo vim /opt/hadoop/etc/hadoop/mapred-site.xml

<property>
   <name>mapreduce.framework.name</name>
   <value>yarn</value>
</property>
<property>
   <name>mapreduce.jobhistory.address</name>
   <value>master:10020</value>
</property>
<property>
   <name>mapreduce.jobhistory.webapp.address</name>
   <value>master:19888</value>
</property>
  • 修改yarn-site.xm

$ sudo vim /opt/hadoop/etc/hadoop/yarn-site.xml

<property>
   <name>yarn.resourcemanager.hostname</name>
   <value>master</value>
</property>
<property>
   <name>yarn.nodemanager.aux-services</name>
   <value>mapreduce_shuffle</value>
</property>
<property>
   <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
   <value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<property>
   <name>yarn.resourcemanager.address</name>
   <value>master:8032</value>
</property>
<property>
   <name>yarn.resourcemanager.scheduler.address</name>
   <value>master:8030</value>
</property>
<property>
   <name>yarn.resourcemanager.resource-tracker.address</name>
   <value>master:8031</value>
</property>
<property>
   <name>yarn.resourcemanager.admin.address</name>
   <value>master:8033</value>
</property>
<property>
   <name>yarn.resourcemanager.webapp.address</name>
   <value>master:8088</value>
</property>

6.將設定檔複製至slave

因為 /opt/hadoop資料夾擁有者為 hadoopuser,我們如果直接用scp複製到 slave1的/opt下,會 permission denied

因此先在slave1下建立/opt/hadoop資料夾,擁有者設為hadoopuser

## slave1 ##
$ cd /opt
$ sudo mkdir hadoop
$ sudo chown hadoopuser:hadoop hadoop/

將檔案從master複製到slave1

## master ##
$ scp -r /opt/hadoop slave1:/opt


7. 在 master中加入 slave的 hostname

編輯 slaves檔案

$sudo vim /opt/hadoop/etc/hadoop/slaves

localhost slave1

8.格式化 Namenode

$ hdfs namenode -format


9.執行hadoop

$ /opt/hadoop/sbin/start-all.sh

如果沒有出意外,會很順利地跑完,如下圖


10.確認是否成功運作

$ jps

用jps可以列出所有執行中的 java process,我們拿來檢核hadoop服務有沒有成功跑起來 會在 master看到

在 slave看到

如果有缺少 DataNode,可以試試刪除 hdfs與 tmp資料夾,並重新格式化 NameNode