Hadoop安裝方式
Hadoop的安裝方式有三種,分別是單機模式,偽分布式模式,偽分布式模式,分布式模式。
單機模式:Hadoop默認模式為非分布式模式(本地模式),無需進行其他配置即可運行。非分布式即單Java進程,方便進行調試。
偽分布式模式:Hadoop可以在單節點上以偽分布式的方式運行,Hadoop進程以分離的Java進程來運行,節點既作為NameNode也作為DataNode,同時,讀取的是HDFS中的文件。
分布式模式:使用多個節點構成集群環境來運行Hadoop。
Hadoop版本
Hadoop 有兩個主要版本,Hadoop 1.x.y 和 Hadoop 2.x.y 系列,Hadoop 2.x 版本在不斷更新,新版是兼容舊版的。
裝好了 Ubuntu 系統之后,在安裝 Hadoop 前還需要做一些必備工作。
創建Hadoop用戶
如果安裝 Ubuntu 的時候不是用的 “hadoop” 用戶,那么需要增加一個名為 hadoop 的用戶。
(1)首先按 ctrl+alt+t 打開終端窗口,輸入如下命令創建新用戶 :
sudo useradd -m hadoop -s /bin/bash
這條命令創建了可以登陸的 hadoop 用戶,並使用 /bin/bash 作為 shell。
- sudo是Ubuntu中一種權限管理機制,管理員可以授權給一些普通用戶去執行一些需要root權限執行的操作。當使用sudo命令時,就需要輸入您當前用戶的密碼。
- 在Linux的終端中輸入密碼,終端是不會顯示任何你當前輸入的密碼,也不會提示你已經輸入了多少字符密碼。而在Windows系統中,輸入密碼一般都會以“*”表示你輸入的密碼字符。
- Ubuntu中終端輸入的命令一般都是使用英文輸入。Linux中英文的切換方式是使用鍵盤“shift”鍵來切換,也可以點擊頂部菜單的輸入法按鈕進行切換。Ubuntu自帶的Sunpinyin中文輸入法已經足夠使用。
- 在Ubuntu終端窗口中,復制粘貼的快捷鍵需要加上“shift”,即粘貼是 “ctrl+shift+v”。
(2)接着使用如下命令設置密碼,可簡單設置為 hadoop,按提示輸入兩次密碼:
sudo passwd hadoop
(3)可為 hadoop 用戶增加管理員權限,方便部署,避免一些棘手的權限問題:
sudo adduser hadoop sudo
(4)最后注銷當前用戶(點擊屏幕右上角的齒輪,選擇注銷),返回登陸界面。在登陸界面中選擇剛創建的 hadoop 用戶進行登陸。
在我的電腦上,第一次注銷用戶后,整個界面只顯示出來桌面背景,圖形界面無法使用,最初以為是我在創建用戶的過程中出了什么問題,重啟了幾次電腦,再次進入Ubuntu后,注銷用戶的功能可以正常使用了。
更新apt
apt(Advanced Packaging Tool)是Linux下的一款安裝包管理工具,是一個客戶/服務器系統。
用 hadoop 用戶登錄后,先更新一下 apt,后續使用 apt 安裝軟件,如果沒更新可能有一些軟件安裝不了。按 ctrl+alt+t 打開終端窗口,執行如下命令:
sudo apt-get update
若出現如下 “Hash校驗和不符” 的提示,可通過更改軟件源來解決。若沒有該問題,則不需要更改。從軟件源下載某些軟件的過程中,可能由於網絡方面的原因出現沒法下載的情況,那么建議更改軟件源。
(1)首先點擊左側任務欄的【系統設置】(齒輪圖標),選擇【軟件和更新】。
(2)點擊 “下載自” 右側的方框,選擇【其他節點】。
(3)在列表中選中【mirrors.aliyun.com】,並點擊右下角的【選擇服務器】,會要求輸入用戶密碼,輸入即可。
(4)接着點擊關閉,此時會提示列表信息過時,點擊【重新載入】。
(5)最后耐心等待更新緩存即可。更新完成會自動關閉【軟件和更新】這個窗口。如果還是提示錯誤,請選擇其他服務器節點如 mirrors.163.com 再次進行嘗試。更新成功后,再次執行 sudo apt-get update
就正常了。
后續需要更改一些配置文件,需要安裝vim。安裝軟件時若需要確認,在提示處輸入 y 即可。
sudo apt-get install vim
vim的常用模式有分為命令模式,插入模式,可視模式,正常模式。
(1)正常模式主要用來瀏覽文本內容。一開始打開vim都是正常模式。在任何模式下按下Esc鍵就可以返回正常模式。
(2)插入編輯模式則用來向文本中添加內容的。在正常模式下,輸入i鍵即可進入插入編輯模式。
(3)退出vim:如果有利用vim修改任何的文本,一定要記得保存。Esc鍵退回到正常模式中,然后輸入:wq即可保存文本並退出vim
安裝SSH、配置SSH無密碼登陸
集群、單節點模式都需要用到 SSH 登陸(類似於遠程登陸,可以登錄某台 Linux 主機,並且在上面運行命令),Ubuntu 默認已安裝了 SSH client,此外還需要安裝 SSH server:
sudo apt-get install openssh-server
安裝后,可以使用如下命令登陸本機:
ssh localhost
此時會有如下提示(SSH首次登陸提示),輸入 yes 。然后按提示輸入密碼 hadoop,這樣就登陸到本機了。
但這樣登陸是需要每次輸入密碼的,我們需要配置成SSH無密碼登陸比較方便。
首先退出剛才的 ssh,就回到了我們原先的終端窗口,然后利用 ssh-keygen 生成密鑰,並將密鑰加入到授權中:
exit # 退出剛才的 ssh localhost
cd ~/.ssh/ # 若沒有該目錄,請先執行一次ssh localhost
ssh-keygen -t rsa # 會有提示,都按回車就可以
cat ./id_rsa.pub >> ./authorized_keys # 加入授權
- 在 Linux 系統中,~ 代表的是用戶的主文件夾,即 “/home/用戶名” 這個目錄,如你的用戶名為 hadoop,則 ~ 就代表 “/home/hadoop/”。 此外,命令中的 # 后面的文字是注釋,只需要輸入前面命令即可。
此時再用 ssh localhost
命令,無需輸入密碼就可以直接登陸了。
安裝Java環境
Java環境可選擇 Oracle 的 JDK,或是 OpenJDK,新版本在 OpenJDK 1.7 下是沒問題的。為圖方便,這邊直接通過命令安裝 OpenJDK 7。
sudo apt-get install default-jre default-jdk
上述安裝過程需要訪問網絡下載相關文件,需要保持聯網狀態。安裝結束以后,需要配置JAVA_HOME環境變量,可以在Linux終端中輸入下面命令打開當前登錄用戶的環境變量配置文件.bashrc:
vim ~/.bashrc
在文件最前面添加如下單獨一行(注意,等號“=”前后不能有空格),然后保存退出:
export JAVA_HOME=/usr/lib/jvm/default-java
接下來,要讓環境變量立即生效,執行如下代碼:
source ~/.bashrc # 使變量設置生效
執行上述命令后,可以檢驗一下是否設置正確:
echo $JAVA_HOME # 檢驗變量值 java -version $JAVA_HOME/bin/java -version # 與直接執行java -version一樣
至此,就成功安裝了Java環境。下面就可以進入Hadoop的安裝。
在JDK安裝過程中,出現了下面的問題:
(1)vim ~/.bashrc打開環境變量配置文件之后,將光標直接移動到了文件的起始位置,然后將“export JAVA_HOME=/usr/lib/jvm/default-java
”粘貼到了文件中,由於不清楚vim的使用,在網上查找到了“保存並退出”的方法,按住Ctrl,再按兩下Z,然后,然后我也忘了發生了啥。
(2)以為經過上面的操作就配置完環境變量了,所以在終端中,輸入了上面代碼框中的三條代碼檢驗環境變量是否配置完成,發現環境變量沒有配置成功。
(3)將終端關閉,重新打開,發現終端的頂部出現了錯誤提示:“export JAVA_HOME=/usr/lib/jvm/default-java # ~/.bashrc:executed by bash(1) for non-login shells”,多次打開、關閉終端,這個提示都無法消失,考慮重啟電腦。
(4)重啟電腦,輸入密碼登錄Jesse用戶,能夠正常使用。注銷用戶后,輸入密碼登錄hadoop用戶,界面黑屏,正中央彈出提示框:“export JAVA_HOME=/usr/lib/jvm/default-java # ~/.bashrc:executed by bash(1) for non-login shells”......,點擊提示框下方的確定按鈕沒有反應。
(5)把這個錯誤的情況反映給了俺哥,分析錯誤原因是我在配置環境變量的時候,將.bashrc文件寫錯了,.bashrc文件主要保存個人的一些個性化設置,如命令別名、路徑等,個人暫時理解成,每次登陸用戶都會啟動執行這個文件,這個文件出錯,會導致用戶無法登錄進圖形界面,俺哥給出的解決方案是,把這個文件修改回去,由於我對這個文件的修改僅限於在文件起始位置添加了那一行代碼,所以需要將那一行代碼刪除。
(6)考慮退出圖形界面,在終端里修改那個文件。按“CTRL+ALT+F2”退出圖形界面,輸入用戶密碼登錄,再輸入vim ~/.bashrc,打開文件,用DEL鍵刪除了前面添加的代碼,“ESC”,“:wq”之后提示“readonly”,表明這個文件不可修改。
(7)思考了一下vim ~/.bashrc這行代碼的意義,決定登錄Jesse用戶,然后在Jesse用戶的圖形界面中找到hadoop文件夾下的.bashrc,在編輯器中刪除第一行代碼,emmmm,沒有保存的權限。
(8)emmmm,考慮到這幾次操作都是因為權限的原因操作失敗,想到了sudo命令,打開終端,輸入sudo vim ~/.bashrc,輸入Jesse用戶的密碼,在編輯器中刪除第一行代碼,然后“:wq”,保存成功了。也就是說,hadoop的.bashrc文件被修改回去了。
(9)注銷Jesse用戶,重新登錄hadoop用戶,在hadoop用戶的圖形界面中,找到了hadoop文件夾下的.bashrc文件,直接在第一行添加“export JAVA_HOME=/usr/lib/jvm/default-java # ”,保存成功,環境變量設置正確。
emmmm,上面這波操作原因是沒有將“export JAVA_HOME=/usr/lib/jvm/default-java # ”單獨添加到.bashrc的第一行。
安裝Hadoop2
如果使用虛擬機方式安裝Ubuntu系統,請用虛擬機中的Ubuntu自帶firefox瀏覽器下載,才能把hadoop文件下載虛擬機ubuntu中。不要使用Windows系統下的瀏覽器下載,文件會被下載到Windows系統中,虛擬機中的Ubuntu無法訪問外部Windows系統的文件。
如果是使用雙系統方式安裝Ubuntu系統,進入Ubuntu系統,在Ubuntu系統打開firefox瀏覽器訪下載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 源代碼,需要進行編譯才可使用。
下載完成后,hadoop文件默認的下載位置是“下載”文件夾。選擇將 Hadoop 安裝至 /usr/local/ 中:
sudo tar -zxf ~/下載/hadoop-2.6.0.tar.gz -C /usr/local # 解壓到/usr/local中(根據所下載的hadoop版本進行修改) cd /usr/local/ sudo mv ./hadoop-2.6.0/ ./hadoop # 將文件夾名改為hadoop(根據所下載的hadoop版本進行修改) sudo chown -R hadoop ./hadoop # 修改文件權限
- tar -zxf ~/下載/spark-2.1.0.tgz -C /usr/local/ #把spark-2.1.0.tgz這個壓縮文件解壓到/usr/local目錄下
- cd .. #返回上一級目錄
- cd ~ #進入到當前Linux系統登錄用戶的主目錄(或主文件夾)。在 Linux 系統中,~代表的是用戶的主文件夾,即“/home
- mv spark-2.1.0 spark #把spark-2.1.0目錄重新命名為spark
- chown -R hadoop:hadoop ./spark # hadoop是當前登錄Linux系統的用戶名,把當前目錄下的spark子目錄的所有權限,賦予給用戶hadoop
Hadoop 解壓后即可使用。輸入如下命令來檢查 Hadoop 是否可用,成功則會顯示 Hadoop 版本信息:
cd /usr/local/hadoop
./bin/hadoop version
- 相對路徑和絕對路徑:注意命令中的相對路徑與絕對路徑,比如
./bin/...
,./etc/...
等包含 ./ 的路徑,均為相對路徑,以 /usr/local/hadoop 為當前目錄。例如在 /usr/local/hadoop 目錄中執行./bin/hadoop version
等同於執行/usr/local/hadoop/bin/hadoop version
。可以將相對路徑改成絕對路徑來執行,但如果你是在主文件夾 ~ 中執行./bin/hadoop version
,執行的會是/home/hadoop/bin/hadoop version
,就不是我們所想要的了。
Hadoop單機配置(非分布式)
Hadoop 默認模式為非分布式模式(本地模式),無需進行其他配置即可運行。非分布式即單 Java 進程,方便進行調試。
可以執行例子來感受下 Hadoop 的運行。Hadoop 附帶了豐富的例子(運行 ./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar
可以看到所有例子),包括 wordcount、terasort、join、grep 等。
- wordcount:假設現在有n個文本,WordCount程序就是利用MR計算模型來統計這n個文本中每個單詞出現的總次數。
- grep:該程序實現的是對指定文檔中指定單詞的詞頻進行計算。
在此我們選擇運行 grep 例子,我們將 input 文件夾中的所有文件作為輸入,篩選當中符合正則表達式 dfs[a-z.]+ 的單詞並統計出現的次數,最后輸出結果到 output 文件夾中。
cd /usr/local/hadoop mkdir ./input cp ./etc/hadoop/*.xml ./input # 將配置文件作為輸入文件 ./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar grep ./input ./output 'dfs[a-z.]+' cat ./output/* # 查看運行結果
- mkdir input #在當前目錄下創建input子目錄
- mkdir -p src/main/scala #在當前目錄下,創建多級子目錄src/main/scala
- cp /home/hadoop/word.txt /usr/local/ #把/home/hadoop/word.txt文件復制到“/usr/local”目錄下
- cat /proc/version #查看Linux系統內核版本信息
- cat /home/hadoop/word.txt #把/home/hadoop/word.txt這個文件全部內容顯示到屏幕上
執行成功后如下所示,輸出了作業的相關信息,輸出的結果是符合正則的單詞 dfsadmin 出現了1次
注意,Hadoop 默認不會覆蓋結果文件,因此再次運行上面實例會提示出錯,需要先將 ./output
刪除。
- rm -r ./output
- rm ./word.txt #刪除當前目錄下的word.txt文件
- rm –r ./test #刪除當前目錄下的test目錄及其下面的所有文件
- rm –r test* #刪除當面目錄下所有以test開頭的目錄和文件
Hadoop偽分布式配置
Hadoop 可以在單節點上以偽分布式的方式運行,Hadoop 進程以分離的 Java 進程來運行,節點既作為 NameNode 也作為 DataNode,同時,讀取的是 HDFS 中的文件。
Hadoop 的配置文件位於 /usr/local/hadoop/etc/hadoop/ 中,偽分布式需要修改2個配置文件 core-site.xml 和 hdfs-site.xml 。Hadoop的配置文件是 xml 格式,每個配置以聲明 property 的 name 和 value 的方式來實現。
修改配置文件 core-site.xml (通過 gedit 編輯會比較方便: gedit ./etc/hadoop/core-site.xml
),將當中的
<configuration> </configuration>
修改為下面配置:(hadoop.tmp.dir表示存放臨時數據的目錄,既包括NameNode的數據,也包括DataNode的數據。該路徑任意指定,只要實際存在這個文件夾即可。如果不設置這樣一個目錄,Linux會給出一個默認的目錄,但是這個臨時目錄在每次退出系統時會被清空掉,下次再運行Hadoop的時候又要重新運行NameNode初始化命令。)(name為fs.defaultFS的值,表示hdfs路徑的邏輯名稱。)
<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>
同樣的,修改配置文件 hdfs-site.xml:(dfs.replication表示副本的數量,偽分布式要設置為1。在HDFS中,每個數據塊,默認有三個副本,要保證冗余性。)(dfs.namenode.name.dir表示本地磁盤目錄,是存儲fsimage文件的地方。)(dfs.datanode.data.dir表示本地磁盤目錄,HDFS數據存放block的地方。)
<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的格式化
./bin/hdfs namenode -format
成功的話,會看到 “successfully formatted” 和 “Exitting with status 0” 的提示,若為 “Exitting with status 1” 則是出錯。
最開始執行./bin/hdfs namenode -format時,顯示某文件無法找到,考慮可能是因為之前已經把之前運行的grep終端關閉了,所以hadoop不在運行的狀態,所以導致沒有執行成功。
重新在終端執行了上一波的grep,執行完畢后,馬上./bin/hdfs namenode -format,終端輸出了一堆亂七八糟的東西。但是和教程中的顯示結果不同,教程中要求出現“successfully formatted” 和 “Exitting with status 0”,但是我的運行結果中最后一項沒有輸出,不知道是不是由於hadoop的版本和教程中的版本不同。
如果在這一步時提示 Error: JAVA_HOME is not set and could not be found. 的錯誤,則說明之前設置 JAVA_HOME 環境變量那邊就沒設置好,請按教程先設置好 JAVA_HOME 變量,否則后面的過程都是進行不下去的。如果已經按照前面教程在.bashrc文件中設置了JAVA_HOME,還是出現 Error: JAVA_HOME is not set and could not be found. 的錯誤,那么,請到hadoop的安裝目錄修改配置文件“/usr/local/hadoop/etc/hadoop/hadoop-env.sh”,在里面找到“export JAVA_HOME=${JAVA_HOME}”這行,然后,把它修改成JAVA安裝路徑的具體地址,比如,“export JAVA_HOME=/usr/lib/jvm/default-java”,然后,再次啟動Hadoop。
接着開啟 NameNode 和 DataNode 守護進程。
./sbin/start-dfs.sh #start-dfs.sh是個完整的可執行文件,中間沒有空格
若出現如下SSH提示"Are you sure you want to continue connecting?",輸入yes即可。\
啟動時可能會出現如下 WARN 提示:WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform… using builtin-java classes where applicable WARN 提示可以忽略,並不會影響正常使用。
啟動完成后,可以通過命令 jps
來判斷是否成功啟動,若成功啟動則會列出如下進程: “NameNode”、”DataNode” 和 “SecondaryNameNode”(如果 SecondaryNameNode 沒有啟動,請運行 sbin/stop-dfs.sh 關閉進程,然后再次嘗試啟動嘗試)。如果沒有 NameNode 或 DataNode ,那就是配置不成功,請仔細檢查之前步驟,或通過查看啟動日志排查原因。
- 同時按Shift和PRTSC可以選取區域截圖,截圖自動保存至圖片文件夾中。
- 同時按CTRL和PRTSC可以對選中窗口進行截圖,截圖自動保存至圖片文件夾中。
- 按PRTSC可以對當前整個界面進行截圖,截圖自動保存至圖片文件夾中。
雖然最后成功啟動NameNode等進程,但是在開啟NameNode和DataNode時,要求輸入密碼,不知道是不是前面設置無密碼SSH登錄失敗。
成功啟動后,可以訪問 Web 界面 http://localhost:50070 查看 NameNode 和 Datanode 信息,還可以在線查看 HDFS 中的文件。
做到這一步是有點慌的,開啟NameNode和DataNode守護進程的時候,需要我輸入密碼,懷疑前面設置SSH無密碼登錄出現了錯誤。執行NameNode格式化的時候,沒有出現返回0,不知道是不是前面哪一步出了錯誤。不過最后偽分布式Hadoop還是啟動成功了。
運行Hadoop偽分布式實例
上面的單機模式,grep 例子讀取的是本地數據,偽分布式讀取的則是 HDFS 上的數據。要使用 HDFS,首先需要在 HDFS 中創建用戶目錄:
./bin/hdfs dfs -mkdir -p /user/hadoop
接着將 ./etc/hadoop 中的 xml 文件作為輸入文件復制到分布式文件系統中,即將 /usr/local/hadoop/etc/hadoop 復制到分布式文件系統中的 /user/hadoop/input 中。我們使用的是 hadoop 用戶,並且已創建相應的用戶目錄 /user/hadoop ,因此在命令中就可以使用相對路徑如 input,其對應的絕對路徑就是 /user/hadoop/input:
./bin/hdfs dfs -mkdir input ./bin/hdfs dfs -put ./etc/hadoop/*.xml input
復制完成后,可以通過如下命令查看文件列表:
./bin/hdfs dfs -ls input
偽分布式運行 MapReduce 作業的方式跟單機模式相同,區別在於偽分布式讀取的是HDFS中的文件(可以將單機步驟中創建的本地 input 文件夾,輸出結果 output 文件夾都刪掉來驗證這一點)。
./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar grep input output 'dfs[a-z.]+'
查看運行結果的命令(查看的是位於 HDFS 中的輸出結果):
./bin/hdfs dfs -cat output/*
結果如下,注意到剛才已經更改了配置文件,所以運行結果不同。
也可以將運行結果取回到本地:
rm -r ./output # 先刪除本地的 output 文件夾(如果存在) ./bin/hdfs dfs -get output ./output # 將 HDFS 上的 output 文件夾拷貝到本機 cat ./output/*
Hadoop 運行程序時,輸出目錄不能存在,否則會提示錯誤 “org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory hdfs://localhost:9000/user/hadoop/output already exists” ,因此若要再次執行,需要執行如下命令刪除 output 文件夾:
./bin/hdfs dfs -rm -r output # 刪除 output 文件夾
運行程序時,輸出目錄不能存在
運行 Hadoop 程序時,為了防止覆蓋結果,程序指定的輸出目錄(如 output)不能存在,否則會提示錯誤,因此運行前需要先刪除輸出目錄。在實際開發應用程序時,可考慮在程序中加上如下代碼,能在每次運行時自動刪除輸出目錄,避免繁瑣的命令行操作:
Configuration conf = new Configuration(); Job job = new Job(conf); /* 刪除輸出目錄 */ Path outputPath = new Path(args[1]); outputPath.getFileSystem(conf).delete(outputPath, true);
若要關閉 Hadoop,則運行
./sbin/stop-dfs.sh
下次啟動 hadoop 時,無需進行 NameNode 的初始化,只需要運行 ./sbin/start-dfs.sh
就可以。