如下備忘本身學習 Hadoop 過程當中學到的內容。html
如 Hadoop 官網 所說,Hadoop 項目包含四部分:java
The project includes these modules:node
Hadoop Common: The common utilities that support the other Hadoop modules.
Hadoop Distributed File System (HDFS™): A distributed file system that provides high-throughput access to application data.
Hadoop YARN: A framework for job scheduling and cluster resource management.
Hadoop MapReduce: A YARN-based system for parallel processing of large data sets.linux
隨着大數據技術的蓬勃發展,人們提起 Hadoop 時,已經將其做爲大數據生態的代名詞。後續大量的大數據相關項目都或多或少地基於或提供了對 Hadoop 模塊的支持。apache
如下對 Hadoop 中 hdfs 和 YARN 模塊的架構進行介紹。編程
在 hdfs 架構中,文件按照配置被拆分紅多個文件塊進行存儲( 默認爲 128M )。基於此,在 hdfs 中主要有兩個角色。其中,NameNode,簡稱 NN,負責應對客戶端的請求、並記錄文件塊的元信息,如文件被如何拆分、如何存儲等;而 DataNode,簡稱 DN,則負責對文件塊進行讀寫,並以心跳包的方式按時上報本身的存活狀況及所存儲文件塊的狀況,用於 NameNode 進行實時容錯排查。安全
在 hdfs 中,有如下內容須要注意:bash
在集羣中,hdfs 會根據配置對文件塊進行冗餘存儲。其副本存儲策略爲:首先挑選網絡拓撲中距離最近的一個節點(通常在同一機架)存儲一份;而後在相鄰機架上挑選兩個節點各存儲一份;若是副本因子大於 3,則後續的副本存儲會隨機挑選節點進行。服務器
對於一個 User 端的請求( 來自 hdfs 交互式終端或編程接口 ),首先會在向 NameNode 中獲取元數據信息。因爲每個文件可能被拆分爲多個文件塊進行存儲,且每個文件塊都含有若干備份,因此 NameNode 會返回該文件所對應的全部文件塊,且對於每個文件塊,都附帶其備份所在的 DataNode 以用於讀取( 備份 DataNode 列表是已排序的 )。網絡
對於每個文件塊,Client Node 會進行以下操做:
上圖中所示的 InputStream
對象是文件系統爲用戶建立的操做節點進行讀取操做的對象。
對於一個 User 端的請求( 來自 hdfs 交互式終端或編程接口 ),首先會在 Client Node 中按照用戶配置的塊大小進行拆分,而後對於每個文件塊,會有以下步驟執行:
上圖中所示的 OutputStream
對象是文件系統爲用戶建立的操做節點進行寫入操做的對象。
有關上述過程的 API 操做過程能夠參考:Hadoop之HDFS文件讀寫過程
對分佈式文件存儲而言,因爲其產生的最初場景就是針對大規模廉價存儲介質,於是其對高可用的保證是足夠到位的。如下就介紹多種故障場景及其容錯機制。
NameNode 上不只記錄了全部文件的元數據,還記錄了全部節點的信息。即每個文件所對應的文件塊及其存儲的 DataNode 列表、以及每個 DataNode 上存儲的文件塊信息與健康狀態。
每隔一段時間,DataNode 都會上報本身所維護的全部文件塊狀況,這一週期性的心跳包機制能夠起到以下做用:
此外,對於「丟失鏈接」的節點,NameNode 還會按期試探其是否恢復了鏈接。
若是發生這種事件,在單 NameNode 狀況下,整個 hdfs 集羣就徹底崩潰了。由於即便文件真正存儲的地方—— DataNode 沒有損壞,因爲失去了元數據,於是也沒法將文件塊拼湊成完整的文件。
但如今通常都會默認開啓 SecondaryNameNode,或採用多 NameNode 節點的方式來規避這一問題。但因爲同一時間只會有一個 NameNode 起做用,且備用 NameNode 中的元信息並非徹底一致的。於是當這一狀況發生時,也極可能發生必定的文件丟失。
只要備份係數是大於一的( 且有多個 DataNode ),則出現這一狀況時,文件不會發生丟失。且因爲心跳包機制,丟失節點上所負責的備份會轉移到其餘節點上。
若是某一文件對應文件塊所存儲於的全部 DataNode 都發生了損壞,則該文件也就丟失了。
但考慮到 NameNode 會在心跳包中對損壞節點上所維護的文件塊進行再分配,除非這些節點在很短期內所有損壞,不然是不會發生這種狀況的。
因爲每個文件塊都有若干個備份,被存儲在不一樣的 DataNode 上,在讀取過程當中,若是有 DataNode 發生了損壞,則會順延地到 DataNode 列表的下一個節點上讀取。
因爲每個文件塊以後都存在校驗機制,若是某一文件塊中的數據發生了損壞,在讀取該文件塊後,能夠經過對比發現這一問題。
此外,因爲 DataNode 也會週期性自檢內部數據的完整性和正確性,並週期性上報這一信息,於是這樣的狀況也不易發生。
若是在某一文件塊的寫入過程當中,須要寫入的 DataNode 列表中存在某一個損壞的節點,則會返回錯誤,Client Node 會將成功的節點和失敗的節點上報 NameNode。因爲在這一狀況發生時,文件塊的備份 DataNode 狀況是不符合要求的,在以後的調整機制中,會對此進行彌補。
如上圖所示,在 Hadoop 1.x 中,任務調度採用 JobTracker 和 TaskTracker 的機制。
對集羣而言,這一架構使得資源調度模型只能適用於 MapReduce 任務。主要基於這個緣由( 還包括如 JobTracker 承擔過多指責而致使的性能問題、單點故障等 ),催生了 YARN 的誕生。YARN 可使得集羣資源爲其上運行的多種框架共享,從而提升了資源的利用率。
在 YARN 架構中,由如下四個重要的角色:
如圖所示,當有 Client 提交任務時,會發生如下步驟:
有關 MapReduce 能夠參考 MapReduce原理與設計思想 或其餘文章。
因爲 NameNode 在啓動後會經過 SSH 完成對 DataNode 節點上守護進程的啓動和中止,因此咱們須要在 NameNode 上配置好對 DataNode 的免密登錄( 注意這裏是單機模式,NameNode 和 DataNode 啓動在同一臺主機上 )。
執行如下命令,生成公私鑰對:
ssh-keygen -t rsa
一路回車後,執行如下命令,配置本地對本地的免登錄:
ssh-copy-id -i ~/.ssh/id_rsa.pub localhost
此後,執行:
ssh root@localhost
即可以無密碼登陸了。
因爲大部分較新版本的大數據軟件都要求使用 JDK1.8 以上,這裏也依次爲準。
首先,由 官網 下載 jdk-8u151-linux-x64.tar.gz。然後解壓到某一目錄( 這裏選擇 /app
,後續均爲此目錄 ):
tar -zxvf jdk-8u151-linux-x64.tar.gz -C /app
以後將其 bin
子目錄添加到環境變量之中。修改 ~/.bash_profile
文件:
JAVA_HOME=/app/jdk1.8.0_151 export PATH=$PATH:$JAVA_HOME/bin
因爲 CDH 版本在企業中使用的比例較高,這裏也選用這個版本。在如下網址中下載 hadoop-2.6.0-cdh5.7.0.tar.gz :
http://archive-primary.cloudera.com/cdh5/cdh/5/
將下載後的文件解壓:
tar -zxvf hadoop-2.6.0-cdh5.7.0.tar.gz -C /app
並將子目錄 bin
其配置到環境變量之中。修改 ~/.bash_profile
,並添加:
HADOOP_HOME=/app/hadoop-2.6.0-cdh5.7.0 export PATH=$PATH:$HADOOP_HOME/bin
$HADOOP_HOME/etc/hadoop/hadoop-env.sh
:將:
export JAVA_HOME=${JAVA_HOME}
修改成:
export JAVA_HOME=/app/jdk1.8.0_151
$HADOOP_HOME/etc/hadoop/core-site.xml
在 configuration
標籤中添加:
<property> <name>fs.default.name</name> <value>hdfs://localhost:8082</value> </property>
$HADOOP_HOME/etc/hadoop/slaves
文件因爲咱們這裏使用的是單機模式的 Hadoop,此文件無需改動。
修改 $HADOOP_HOME/etc/hadoop/hdfs-site.xml
,在 configuration
標籤中添加:
<property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/app/hdfs_tmp/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/app/hdfs_tmp/dfs/data</value> </property>
執行如下命令以格式化 NameNode。此命令的執行與 hdfs-site.xml
中配置的 dir
有關。此外,因爲每次執行都會重置文件系統,須要特別注意誤操做。
hdfs namenode -format
執行如下指令:
cd $HADOOP_HOME/sbin ./start-dfs.sh
咱們可使用如下兩種方式檢驗 hdfs 的啓動狀況:
jps
命令執行如下命令:
jps
查看是否已經啓動了以下進程:
DataNode NameNode SecondaryNameNode
經過訪問:
http://${IP}:50070
能夠查看 hdfs 的啓動狀況。
當對 hdfs 進行操做,如使用 hdfs dfs -mkdir /test
時,可能會出現:Hadoop Name node is in safe mode
的提示。此時能夠經過如下命令移除安全模式:
hdfs dfsadmin -safemode leave
將 $HADOOP_HOME/etc/hadoop/mapred-site.xml.template
複製一份名爲: mapred-site.xml
,爲其 configuration
添加內容:
<property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>
修改 $HADOOP_HOME/etc/hadoop/yarn-site.xml
,爲其 configuration
添加內容:
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property>
使用如下命令啓動 YARN:
$HADOOP_HOME/sbin/start-yarn.sh
一樣的,咱們可使用如下兩種方式檢驗 YARN 的啓動狀況:
jps
命令:jps
查看是否已經啓動了以下進程:
ResourceManager NodeManager
經過訪問:
http://${IP}:8088
能夠查看 yarn 的啓動狀況。
咱們可使用官方提供的測試用例來測試效果:
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.7.0.jar pi 2 3
在 $HADOOP_HOME/sbin
下,咱們能夠經過:
./start-all.sh
的方式啓動 YARN 和 hdfs,但咱們會收到提示:
This script is Deprecated. Instead use start-dfs.sh and start-yarn.sh
這裏只介紹搭建集羣時,須要額外進行的配置。
假設咱們如今有三臺機器,分別爲:
192.168.0.1(主) 192.168.0.2(從) 192.168.0.3(從)
如上,咱們把 192.168.0.1
當作主節點。由上述內容可知,該機器會在以後承擔 hdfs 中 NameNode
和 YARN 中 ResourceManager
的角色。
由此,咱們能夠知道,在預期搭建的集羣中,承擔 DataNode
和 NodeManager
的爲:
192.168.0.1 192.168.0.2 192.168.0.3
首先,咱們要確保三臺機器都已經安裝了 SSH。且都已執行如下代碼生成了公私鑰對:
ssh-keygen -t rsa
因爲 NameNode
須要經過 SSH 對 DataNode
進行操做,因此咱們須要爲 192.168.0.1
配置好對其餘節點( 包括本身 )的免登錄,即在 192.168.0.1
上執行:
ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.0.1 ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.0.2 ssh-copy-id -i ~/.ssh/id_rsa.pub 192.168.0.3
首先,咱們須要在主節點 192.168.0.1
上將 JDK 和 Hadoop 下載解壓到 /app
目錄,並按照單節點方式對其進行了配置( 包括環境變量和 Hadoop 配置 )。
接着咱們須要針對集羣狀況對以前的配置進行必定修改。
該文件無需額外修改。
該文件無需額外修改。
咱們須要將副本系數改成 3,而關於 name.dir
和 data.dir
的配置能夠不作修改:
<property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/app/hdfs_tmp/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/app/hdfs_tmp/dfs/data</value> </property>
因爲 hdfs 默認的副本系數即爲 3,這裏也能夠省略有關 dfs.replication
的配置。
除了以前對 nodemanager.aux-services
的修改,咱們還須要添加一些配置,修改後的結果爲:
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.hostname</name> <value>192.168.0.1</value> </property>
注意:因爲這些配置文件會被分發到各個子節點,resourcemanager.hostname
切勿寫成 localhost
該文件無需額外修改。
該文件與上述文件在同一路徑下,在集羣配置中,咱們須要對此進行修改:
192.168.0.1 192.168.0.2 192.168.0.3
注意,因爲咱們在主節點上也運行了一個 DataNode
和 NodeManager
,故而該節點既起到了主節點做用,也承擔了從節點的服務。
按照以前的作法,咱們已經對主節點完成了 JDK、Hadoop 的安裝和配置,此時能夠直接將該文件夾經過如下指令發送到其餘其餘兩臺機器上:
scp -r /app 192.168.0.2:/ scp -r /app 192.168.0.3:/
這樣一來,只需等待傳輸結束,就能夠在其餘兩臺機器上完成相關軟件的安裝和配置。
因爲咱們還在 ~/.bash_profile
中配置了環境變量,因此該文件也須要發送到兩臺從服務器上:
scp ~/.bash_profile 192.168.0.2:~/ scp ~/.bash_profile 192.168.0.3:~/
這以後,咱們須要登陸到兩臺從服務器上,使用如下命令使該配置文件生效:
source ~/.bash_profile
在主節點上,執行如下指令,進行 NameNode 的格式化:
hdfs namenode -format
注意,若是在先前的單機配置中已經進行過了格式化,須要將原有的 hdfs_tmp
文件夾刪除(該目錄與 hdfs-site.xml
中配置的 dir
有關),再從新進行格式化。
在主節點上,進入 $HADOOP_HOME/sbin
,執行:
./start-all
在主節點上,使用 jps
能夠查看有如下進程啓動:
DataNode NameNode SecondaryNameNode ResourceManager NodeManager
而在從節點上,則爲:
DataNode NodeManager
自此,集羣已經成功的搭建。