1. 程式人生 > >Hadoop:Hadoop單機偽分散式的安裝和配置

Hadoop:Hadoop單機偽分散式的安裝和配置

因為lz的linux系統已經安裝好了很多開發環境,可能下面的步驟有遺漏。

之前是在docker中配置的hadoop單機偽分散式[ ],並且在docker只有root使用者,所有沒有許可權問題存在。

這裡直接在linux下配置,主要是為了能用netbeans ide除錯hadoop程式,並且使用的使用者就是開機時登入的使用者pika。

本教程配置環境:

ubuntu14.04(Ubuntu 12.04 /32位、64位都ok! lz是直接使用的雙系統中的linux)

hadoop 2.6.4 (原生 Hadoop 2都ok!)

jdk1.7.0_101(應該1.6+應該都ok!)

皮blog

基本環境配置

安裝和配置
Java
環境

在主機上從Oracle官方網站下載對應版本的JDK安裝包

$ sudo vim ~/.bashrc 或者/etc/profile
第一行“...”的path末尾加上:${JAVA_HOME}/bin,後面export路徑

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

export JAVA_HOME=/opt/jdk1.8.0_73
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib

export PATH=$PATH:${JAVA_HOME}/bin


$ sudo update-alternatives --install /usr/bin/java java /opt/jdk1.8.0_73/bin/java 300;

sudo update-alternatives --install /usr/bin/javac javac /opt/jdk1.8.0_73/bin/javac 300;
sudo update-alternatives --install /usr/bin/javah javah /opt/jdk1.8.0_73/bin/javah 300;
sudo update-alternatives --install /usr/bin/jar jar /opt/jdk1.8.0_73/bin/jar 300


. ~/.bashrc 或者/etc/profile
測試是否安裝成功
[email protected]:/#java -version

安裝SSH、配置SSH無密碼登陸

叢集、單節點模式都需要用到 SSH (ssh must be installed and sshd must be running to use the Hadoop scripts that manage remote Hadoop daemons,而這並沒有說一定要ssh localhost登入!!!lz親測,執行hadoop不需要ssh localhost登入,只要安裝並運行了sshd就可以了),Ubuntu 預設已安裝了 SSH client,還需要安裝 SSH server:
pika:~$sudo apt-get install -y openssh-server

編輯sshd的配置檔案pika:~$sudo vim /etc/ssh/sshd_config,將其中大概88行,UsePAM引數設定成“no”
啟動sshd服務pika:~$sudo /etc/init.d/ssh start

#每次重啟都要重新啟動,所以要加入到profile中開機自啟

pika:~$sudo vim /etc/profile

其中加入一行/etc/init.d/ssh start


檢視ssh服務狀態 pika:~$ps -e | grep ssh
29856 ?        00:00:00 sshd

安裝後設置ssh

可以使用如下命令登陸本機:ssh localhost
此時會有SSH首次登陸提示,輸入 no,(如果輸入yes再輸入密碼,這樣就登陸到本機了,但這樣登陸是需要每次輸入密碼的,我們需要配置成SSH無密碼登陸比較方便,如果進去了首先退出剛才的 ssh)。
回到我們原先的終端視窗,然後利用 ssh-keygen 生成金鑰,並將金鑰加入到授權中:
exit                           # 退出剛才的 ssh localhost,或者用ctrl+d

cd ~/.ssh/                     # 若沒有該目錄,請先執行一次ssh localhost
ssh-keygen -t rsa              # 會有提示,都按回車就可以,如果已經存在,直接進入下一步就可以了(lz的就存在,說明以前已經用過這個)
cat ./id_rsa.pub >> ./authorized_keys  # 加入授權,把id_rsa.pub 追加到授權的 key 裡面去

關於設定hadoop使用者 (前面說了,其實完全可以不用)

皮blog


Hadoop的安裝和配置

Hadoop 2 可以通過 http://mirror.bit.edu.cn/apache/hadoop/common/ 或者 http://mirrors.cnnic.cn/apache/hadoop/common/ 下載,一般選擇下載最新的穩定版本,即下載 “stable” 下的 hadoop-2.x.y.tar.gz 這個格式的檔案,這是編譯好的,另一個包含 src 的則是 Hadoop 原始碼,需要進行編譯才可使用。lz下載的是hadoop-2.6.4。

安裝Hadoop 至 /usr/local/ 中

下載hadoop到/usr/local並解壓

pika:~$sudo wget http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-2.6.4/hadoop-2.6.4.tar.gz -P /usr/local

pika:~$cd /usr/local/

pika:/usr/local$sudo tar -zxf hadoop-2.6.4.tar.gz
pika:/usr/local$sudo ln -s /usr/local/hadoop-2.6.4 /usr/local/hadoop        #設定軟連結,這樣兩個目錄是一樣的了
pika:/usr/local$ls /usr/local/hadoop
bin  etc  include  lib  libexec  LICENSE.txt  NOTICE.txt  README.txt  sbin  share

sudo chown -R hadoop ./hadoop       # -R遞迴修改檔案所有者為hadoop

檢查 Hadoop 是否可用

pika:/usr/local$hadoop/bin/hadoop version
Hadoop 2.6.4
Subversion https://git-wip-us.apache.org/repos/asf/hadoop.git -r 5082c73637530b0b7e115f9625ed7fac69f937e6
Compiled by jenkins on 2016-02-12T09:45Z
Compiled with protoc 2.5.0
From source with checksum 8dee2286ecdbbbc930a6c87b65cbc010
This command was run using /usr/local/hadoop-2.6.4/share/hadoop/common/hadoop-common-2.6.4.jar

皮blog

Hadoop單機偽分散式配置

{如上所述,下面的安裝和執行其實根本沒用到ssh localhost登入,也可以執行!如果實在要ssh登入只用在start-dfs.sh執行前登入就可以了}

Hadoop 可以在單節點上以偽分散式的方式執行,Hadoop 程序以分離的 Java 程序來執行,節點既作為 NameNode 也作為 DataNode,同時,讀取的是 HDFS 中的檔案。
Hadoop 的配置檔案位於 /usr/local/hadoop/etc/hadoop/ 中,偽分散式需要修改2個配置檔案 core-site.xml 和 hdfs-site.xml 。Hadoop的配置檔案是 xml 格式,每個配置以宣告 property 的 name 和 value 的方式來實現。

Hadoop執行命令目錄加入到path中

pika:~$sudo vim ~/.bashrc  或者/etc/profile

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
PATH="$PATH:${JAVA_HOME}/bin:${SPARK_HOME}/bin:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin"
export PATH
export JAVA_HOME=/opt/jdk1.8.0_73
export JRE_HOME=${JAVA_HOME}/jre

export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/

export CLASSPATH=$CLASSPATH:/usr/local/hadoop-2.6.4/etc/hadoop:/usr/local/hadoop-2.6.4/share/hadoop/common/lib/*:/usr/local/hadoop-2.6.4/share/hadoop/common/*:/usr/local/hadoop-2.6.4/share/hadoop/hdfs:/usr/local/hadoop-2.6.4/share/hadoop/hdfs/lib/*:/usr/local/hadoop-2.6.4/share/hadoop/hdfs/*:/usr/local/hadoop-2.6.4/share/hadoop/yarn/lib/*:/usr/local/hadoop-2.6.4/share/hadoop/yarn/*:/usr/local/hadoop-2.6.4/share/hadoop/mapreduce/lib/*:/usr/local/hadoop-2.6.4/share/hadoop/mapreduce/*:/usr/local/hadoop-2.6.4/contrib/capacity-scheduler/*.jar

export HADOOP_HOME=/usr/local/hadoop-2.6.4

export SPARK_HOME=/opt/spark

export PYSPARK_PYTHON=python3

Note: HADOOP_HOME也可以使用軟連結;lz之前配置過spark,裡面有spark的配置,不用管,主要是加色的部分加上去就ok了。

pika:~$ . ~/.bashrc  或者/etc/profile    #下次重啟後不用

pika:~$echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/jdk1.8.0_73/bin:/opt/spark/bin:/usr/local/hadoop-2.6.4/bin:/usr/local/hadoop-2.6.4/sbin

改配置檔案 core-site.xml和hdfs-site.xml

pika:~$cd /usr/local/hadoop

pika:/usr/local/hadoop$sudo vim etc/hadoop/core-site.xml

將當中的<configuration></configuration>修改成:

<configuration>
        <property>
             <name>hadoop.tmp.dir</name>
             <value>file:/usr/local/hadoop/tmp</value>
             <description>Abase for other temporary directories.</description>
        </property>
        <property>
             <name>fs.defaultFS</name>
             <value>hdfs://localhost:9000</value>
        </property>

</configuration>

Note: 我去,設定了vim後,vim中貼上都會自動縮排,所以可以先在gedit將前面的空格刪了:^\s+。

同樣修改配置檔案 hdfs-site.xml:

pika:/usr/local/hadoop$sudo vim etc/hadoop/hdfs-site.xml

<configuration>
        <property>
             <name>dfs.replication</name>
             <value>1</value>
        </property>
        <property>
             <name>dfs.namenode.name.dir</name>
             <value>file:/usr/local/hadoop/tmp/dfs/name</value>
        </property>
        <property>
             <name>dfs.datanode.data.dir</name>
             <value>file:/usr/local/hadoop/tmp/dfs/data</value>
        </property>

</configuration>

Hadoop配置檔案說明

Hadoop 的執行方式是由配置檔案決定的(執行 Hadoop 時會讀取配置檔案),因此如果需要從偽分散式模式切換回非分散式模式,需要刪除 core-site.xml 中的配置項。
此外,偽分散式雖然只需要配置 fs.defaultFS 和 dfs.replication 就可以執行,不過若沒有配置 hadoop.tmp.dir 引數,則預設使用的臨時目錄為 /tmp/hadoo-hadoop,而這個目錄在重啟時有可能被系統清理掉,導致必須重新執行 format 才行。

同時也指定 dfs.namenode.name.dir 和 dfs.datanode.data.dir,否則在接下來的步驟中可能會出錯。

配置完成後,執行 NameNode 的格式化

hadoop中配置JAVA_HOME

pika:~$sudo vim /usr/local/hadoop-2.6.4/libexec/hadoop-config.sh

在大概161行位置加上export JAVA_HOME=/opt/jdk1.8.0_73

$cd /usr/local/hadoop

pika:/usr/local/hadoop$sudo bin/hdfs namenode -format
成功的話,會看到 “successfully formatted” 和 “Exitting with status 0” 的提示,若為 “Exitting with status 1” 則是出錯。

開啟 NameNode 和 DataNode 守護程序

對hadoop安裝目錄執行命令對檔案敞開許可權,否則會出錯Starting namenodes on [localhost] localhost: mkdir: cannot create directory ‘/usr/soft/hadoop-2.6.3/logs’: Permission denied

pika:~$sudo chown -R pika:pika /usr/local/hadoop-2.6.4
pika:~$sudo chmod u+w -R /usr/local/hadoop-2.6.4

Note: lz將hadoop目錄所有權修改成了當前使用者pika及使用者組pika,並給目錄遞迴加上的當前使用者pika的寫許可權。當然也可以直接給所有使用者都加上w許可權:$sudo chmod a+w -R /usr/local/hadoop-2.6.4/,不過lz覺得這樣可能會有安全隱患。

pika:~$start-dfs.sh
Note: 若出現SSH提示,輸入yes即可

Note: 出現上面結果不一定就是說hadoop執行正確了,要通過下面的jps檢視。

如果執行上面的start-dfs.sh出錯,再次執行可能會出錯,一般都是因為沒有stop相關的程式。所以要通過stop-dfs.sh實現。

通過jps檢視啟動的Hadoop程序

啟動完成後,可以通過命令 jps 來判斷是否成功啟動,若成功啟動則會列出如下程序: “NameNode”、”DataNode” 和 “SecondaryNameNode”(如果 SecondaryNameNode 沒有啟動,請執行 sbin/stop-dfs.sh 關閉程序,然後再次嘗試啟動嘗試)。如果沒有 NameNode 或 DataNode ,那就是配置不成功,請仔細檢查之前步驟,或通過檢視啟動日誌排查原因。

pika:~$jps


通過web介面訪問

如果是linux或者虛擬機器配置的hadoop,成功啟動後,可以訪問 Web 介面 http://localhost:50070 檢視 NameNode 和 Datanode 資訊,還可以線上檢視 HDFS 中的檔案。

啟動Hadoop可能的錯誤及解決

Hadoop無法正常啟動的解決方法
一般可以檢視啟動日誌來排查原因,注意幾點:
啟動時會提示形如 “DBLab-XMU: starting namenode, logging to /usr/local/hadoop/logs/hadoop-hadoop-namenode-DBLab-XMU.out”,其中 DBLab-XMU 對應你的機器名,但其實啟動日誌資訊是記錄在 /usr/local/hadoop/logs/hadoop-hadoop-namenode-DBLab-XMU.log 中,所以應該檢視這個字尾為 .log 的檔案;
每一次的啟動日誌都是追加在日誌檔案之後,所以得拉到最後面看,對比下記錄的時間就知道了。
一般出錯的提示在最後面,通常是寫著 Fatal、Error、Warning 或者 Java Exception 的地方。
可以在網上搜索一下出錯資訊,看能否找到一些相關的解決方法。

如:

FATAL org.apache.hadoop.hdfs.server.namenode.NameNode: Failed to start namenode.

org.apache.hadoop.hdfs.server.common.InconsistentFSStateException: Directory /usr/local/hadoop-2.6.4/tmp/dfs/name is in an inconsistent state: storage directory does not exist or is not accessible.

這個錯誤是一般都是因為沒有如上sudo vim etc/hadoop/hdfs-site.xml配置,或者是沒有如上修改當前使用者write目錄的許可權。

錯誤1:

啟動時可能會出現如下 WARN 提示:WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform… using builtin-java classes where applicable。該 WARN 提示可以忽略,並不會影響正常使用(該 WARN 可以通過

編譯 Hadoop 原始碼解決)。

錯誤2:

出錯:Starting namenodes on [localhost]
localhost: Error: JAVA_HOME is not set and could not be found.

明明已經設定了,並且$ echo $JAVA_HOME
/opt/jdk1.8.0_91成功輸出!

解決方案:

如上提到的,要在hadoop中配置JAVA_HOME

pika:~$sudo vim /usr/local/hadoop-2.6.4/libexec/hadoop-config.sh

在大概161行位置加上export JAVA_HOME=/opt/jdk1.8.0_73


錯誤3:

啟動 Hadoop 時提示 Could not resolve hostname
如果啟動 Hadoop 時遇到輸出非常多“ssh: Could not resolve hostname xxx”的異常情況
這個並不是 ssh 的問題,可通過設定 Hadoop 環境變數來解決。首先按鍵盤的 ctrl + c 中斷啟動,然後在 ~/.bashrc 中,增加如下兩行內容(設定過程與 JAVA_HOME 變數一樣,其中 HADOOP_HOME 為 Hadoop 的安裝目錄):
export HADOOP_HOME=/usr/local/hadoop
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
執行 source ~/.bashrc 使變數設定生效,然後再次執行 ./sbin/start-dfs.sh 啟動 Hadoop。

錯誤4:DataNode 沒有啟動

一般情況下,若是 DataNode 沒有啟動,可嘗試如下的方法(注意這會刪除 HDFS 中原有的所有資料,如果原有的資料很重要請不要這樣做):
./sbin/stop-dfs.sh   # 關閉
rm -r ./tmp 刪除 tmp 檔案,注意這會刪除 HDFS 中原有的所有資料
./bin/hdfs namenode -format 重新格式化 NameNode
./sbin/start-dfs.sh  # 重啟

Hadoop單機偽分散式執行例項

單機模式grep 例子讀取的是本地資料,偽分散式讀取的則是 HDFS 上的資料。這裡我們還要自己寫java程式碼,並在java程式碼中引入hadoop packages。

如果你是自己建立的使用者,並且沒有使用者目錄的話,要使用 HDFS,首先需要在 HDFS 中建立使用者目錄:
./bin/hdfs dfs -mkdir -p /user/hadoop
接著將檔案複製到分散式檔案系統中。

我們使用的是 hadoop 使用者,並且已建立相應的使用者目錄 /user/hadoop ,因此在命令中就可以使用相對路徑如 input,其對應的絕對路徑就是 /user/hadoop/input

新增hadoop classpath

這一步已經在上面的path環境配置中配置過了

pika:/media/pika/files/mine/java_workspace/BDMS/src/hw2$hadoop classpath

/usr/local/hadoop-2.6.4/etc/hadoop:/usr/local/hadoop-2.6.4/share/hadoop/common/lib/*:/usr/local/hadoop-2.6.4/share/hadoop/common/*:/usr/local/hadoop-2.6.4/share/hadoop/hdfs:/usr/local/hadoop-2.6.4/share/hadoop/hdfs/lib/*:/usr/local/hadoop-2.6.4/share/hadoop/hdfs/*:/usr/local/hadoop-2.6.4/share/hadoop/yarn/lib/*:/usr/local/hadoop-2.6.4/share/hadoop/yarn/*:/usr/local/hadoop-2.6.4/share/hadoop/mapreduce/lib/*:/usr/local/hadoop-2.6.4/share/hadoop/mapreduce/*:/usr/local/hadoop-2.6.4/contrib/capacity-scheduler/*.jar

Note:要將hadoop classpath輸出加入到CLASSPATH中,Hadoop provides a convenient utility to get the CLASSPATH information you need. Run "hadoop classpath" This should give you the information you need set your classpath for compiling your code.否則java程式碼中import package org.apache.hadoop.*會出錯:javac .java error: package org.apache.hadoop.conf does not exist...[package org.apache.hadoop.fs does not exist]

#啟動hadoop並將input檔案copy到hdfs中

pika:~$hdfs dfs -ls /
pika:~$hdfs dfs -mkdir -p /pika/input
pika:~$hdfs dfs -ls /

drwxr-xr-x   - pika supergroup          0 2016-06-10 19:22 /pika

將輸入檔案copy到hadoop hdfs檔案系統中供其使用(.java檔案是可以不用copy進去的)

pika:~$hdfs dfs -put /media/pika/files/mine/java_workspace/BDMS/src/hw2/*input* /pika/input

pika:~$hdfs dfs -ls /pika/input

-rw-r--r--   1 pika supergroup        165 2016-06-10 19:28 /pika/input/example-input.txt
drwxr-xr-x   - pika supergroup          0 2016-06-10 19:28 /pika/input/part1-input

Note: /media/pika/files/mine/java_workspace/BDMS/src/hw2/目錄下的檔案有哪些可以在這裡下載[avg-time hadoop程式]

#編譯執行java的hadoop程式

pika:~$cd /media/pika/files/mine/java_workspace/BDMS/src/hw2/
pika:/media/pika/files/mine/java_workspace/BDMS/src/hw2$rm -f *.class *.jar#移除已有的java編譯檔案

pika:/media/pika/files/mine/java_workspace/BDMS/src/hw2$ javac AvgTime.java
pika:/media/pika/files/mine/java_workspace/BDMS/src/hw2$jar cfm AvgTime.jar AvgTime-manifest.txt AvgTime*.class
pika:/media/pika/files/mine/java_workspace/BDMS/src/hw2$hdfs dfs -rm -f -r /pika/output             #移除已有的output資料夾目錄

pika:/media/pika/files/mine/java_workspace/BDMS/src/hw2$hadoop jar ./AvgTime.jar /pika/input/example-input.txt /pika/output             #執行hadoop程式
pika:/media/pika/files/mine/java_workspace/BDMS/src/hw2$hdfs dfs -cat '/pika/output/part-*' #檢視輸出
1.2.3.4 18811001100    2 28.500
alpha 1.2.3.4    2 20.200
beta alpha    2 4.100

Note: Hadoop 執行程式時,輸出目錄不能存在,否則會提示錯誤 “org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory hdfs://localhost:9000/user/hadoop/output already exists” ,因此若要再次執行,需要執行如下命令刪除 output 資料夾:   ./bin/hdfs dfs -rm -r output

執行 Hadoop 程式時,為了防止覆蓋結果,程式指定的輸出目錄(如 output)不能存在,否則會提示錯誤,因此執行前需要先刪除輸出目錄。在實際開發應用程式時,可考慮在程式中加上如下程式碼,能在每次執行時自動刪除輸出目錄,避免繁瑣的命令列操作:
Configuration conf = new Configuration();
Job job = new Job(conf);
/* 刪除輸出目錄 */
Path outputPath = new Path(args[1]);
outputPath.getFileSystem(conf).delete(outputPath, true);

ref: