Hadoop-HDFS(HDFS-HA)

HDFS(Hadoop Distributed File System) 分佈式文件系統,HDFS是一個高度容錯性的系統,適合部署在廉價的機器上。HDFS能提供高吞吐量的數據訪問,很是適合大規模數據集上的應用.由NameNode,若干DataNode,以及Secondary NameNode組成。node

 HDFS組成架構

 

 HDFS文件塊大小:

 

 HDFS客戶端Shell操做

經常使用命令實操 (0)啓動Hadoop集羣(方便後續的測試) [atguigu@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh [atguigu@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh1)-help:輸出這個命令參數 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -help rm2)-ls: 顯示目錄信息 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -ls /3)-mkdir:在HDFS上建立目錄 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -mkdir -p /sanguo/shuguo (4)-moveFromLocal:從本地剪切粘貼到HDFS [atguigu@hadoop102 hadoop-2.7.2]$ touch kongming.txt [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs  -moveFromLocal  ./kongming.txt  /sanguo/shuguo (5)-appendToFile:追加一個文件到已經存在的文件末尾 [atguigu@hadoop102 hadoop-2.7.2]$ touch liubei.txt [atguigu@hadoop102 hadoop-2.7.2]$ vi liubei.txt 輸入 san gu mao lu [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -appendToFile liubei.txt /sanguo/shuguo/kongming.txt (6)-cat:顯示文件內容 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -cat /sanguo/shuguo/kongming.txt (7)-chgrp 、-chmod、-chown:Linux文件系統中的用法同樣,修改文件所屬權限 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs  -chmod  666  /sanguo/shuguo/kongming.txt [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs  -chown  atguigu:atguigu   /sanguo/shuguo/kongming.txt (8)-copyFromLocal:從本地文件系統中拷貝文件到HDFS路徑去 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -copyFromLocal README.txt /9)-copyToLocal:從HDFS拷貝到本地 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -copyToLocal /sanguo/shuguo/kongming.txt ./10)-cp :從HDFS的一個路徑拷貝到HDFS的另外一個路徑 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -cp /sanguo/shuguo/kongming.txt /zhuge.txt (11)-mv:在HDFS目錄中移動文件 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -mv /zhuge.txt /sanguo/shuguo/12)-get:等同於copyToLocal,就是從HDFS下載文件到本地 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -get /sanguo/shuguo/kongming.txt ./13)-getmerge:合併下載多個文件,好比HDFS的目錄 /user/atguigu/test下有多個文件:log.1, log.2,log.3,... [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -getmerge /user/atguigu/test/* ./zaiyiqi.txt (14)-put:等同於copyFromLocal [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -put ./zaiyiqi.txt /user/atguigu/test/ (15)-tail:顯示一個文件的末尾 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -tail /sanguo/shuguo/kongming.txt (16)-rm:刪除文件或文件夾 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -rm /user/atguigu/test/jinlian2.txt (17)-rmdir:刪除空目錄 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -mkdir /test [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -rmdir /test (18)-du統計文件夾的大小信息 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -du -s -h /user/atguigu/test 2.7 K /user/atguigu/test [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -du -h /user/atguigu/test 1.3 K /user/atguigu/test/README.txt 15 /user/atguigu/test/jinlian.txt 1.4 K /user/atguigu/test/zaiyiqi.txt (19)-setrep:設置HDFS中文件的副本數量 [atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -setrep 10 /sanguo/shuguo/kongming.txt
 圖3-3 HDFS副本數量 這裏設置的副本數只是記錄在NameNode的元數據中,是否真的會有這麼多副本,還得看DataNode的數量。由於目前只有3臺設備,最多也就3個副本,只有節點數的增長到10臺時,副本數才能達到10。

HDFS讀寫流程

HDFS寫流程(上傳文件)

 

1)客戶端經過Distributed FileSystem模塊NameNode請求上傳文件,NameNode檢查目標文件是否已存在,父目錄是否存在。apache

2NameNode返回是否能夠上傳。bootstrap

3)客戶端請求第一個 Block上傳到哪幾個DataNode服務器上。promise

4NameNode返回3DataNode節點,分別爲dn一、dn二、dn3。瀏覽器

5)客戶端經過FSDataOutputStream模塊請求dn1上傳數據,dn1收到請求會繼續調用dn2,而後dn2調用dn3,將這個通訊管道創建完成。緩存

6dn一、dn二、dn3逐級應答客戶端。安全

7)客戶端開始往dn1上傳第一個Block(先從磁盤讀取數據放到一個本地內存緩存),以Packet爲單位,dn1收到一個Packet就會傳給dn2,dn2傳給dn3;dn1每傳一個packet會放入一個應答隊列等待應答服務器

8)當一個Block傳輸完成以後,客戶端再次請求NameNode上傳第二個Block的服務器。(重複執行3-7步)。網絡

在HDFS寫數據的過程當中,NameNode選擇距離待上傳數據最近距離DataNode接收數據。那麼這個最近距離怎麼計算呢架構

節點距離:兩個節點到達最近的共同祖先的距離總和。

DN1是最近的,DN2和DN3是根據第一個節點DN1選出來的;

第二次的DN四、DN五、DN6可能跟第一次傳輸的DN同樣,也可能不同取決於內部集羣的情況;兩次返回的DN都是獨立的。

N1與N2之間的距離爲2;(找線條數)

假設N一、N二、N3三臺機器,從N1上傳數據,則最短的節點就是它自己0;

後兩個的選擇是根據機架感知來選:

HDFS讀數據流程(下載)

 

1)客戶端經過Distributed FileSystemNameNode請求下載文件,NameNode經過查詢元數據,找到文件塊所在的DataNode地址。

2)挑選一臺DataNode就近原則,而後隨機)服務器,請求讀取數據

3DataNode開始傳輸數據給客戶端(從磁盤裏面讀取數據輸入流,以Packet爲單位來作校驗)。

4)客戶端以Packet爲單位接收,先在本地緩存,而後寫入目標文件。

NameNode和SecondaryNameNode

NN和2NN工做機制

思考NameNode存儲在哪裏?

若是將NameNode節點元數據存於磁盤中,由於須要常常進行隨機訪問,且還響應客戶端的請求,效率低下。所以,要將元數據防於內存中,可是若是斷電,內存中的數據就會丟失,集羣沒法工做了。所以在磁盤中備份元數據的FsImage。

可是這樣會帶來新的問題就是,在更新內存中的數據同時,還要同時更新FsImage,這樣效率低下,所以,引入Edits文件(只進行追加操做,效率很高)。每當元數據有更新或者添加元數據時,修改內存中的元數據並追加到Edits中。這樣,一旦NameNode節點斷電,能夠經過FsImageEdits的合併,合成元數據。

可是若是長時間添加數據到Edits中,致使文件過大,若是某天斷電,那麼回覆元數據時間很長,所以,須要按期合併FsImage和Edits文件,可是這個操做由NameNode節點完成,效率低下。所以引入新節點SecondaryNameNode,專門用於FsImage和Rdits按期合併。

NN和2NN工做機制如圖所示:

 Fsimage:NameNode內存中元數據序列化後造成的文件。包含HDFS文件系統的全部目錄和文件inode的序列化信息;是HDFS文件系統元數據的永久性檢查點;

 Edits:記錄客戶端更新--增刪改元數據信息的每一步操做。

 NameNode啓動時,先滾動Edits並生成一個空的edits.inprogress,而後加載Edits和Fsimage到內存中,此時NameNode內存就持有最新的元數據信息。

1. 第一階段:NameNode啓動

1)第一次啓動NameNode格式化後建立Fsimage和Edits文件。若是不是第一次啓動,直接加載編輯日誌和鏡像文件到內存。

2客戶端對元數據進行增刪改的請求

3NameNode記錄操做日誌,更新滾動日誌

4NameNode在內存中對數據進行增刪改

2. 第二階段:Secondary NameNode工做

1Secondary NameNode詢問NameNode是否須要CheckPoint直接帶回NameNode是否檢查結果。

2Secondary NameNode請求執行CheckPoint。

3NameNode滾動正在寫的Edits日誌

4)將滾動前的編輯日誌和鏡像文件拷貝到Secondary NameNode。

5Secondary NameNode加載編輯日誌和鏡像文件到內存,併合並。

6生成新的鏡像文件fsimage.chkpoint。

7拷貝fsimage.chkpointNameNode

8NameNodefsimage.chkpoint從新命名成fsimage。

NN和2NN工做的詳解:

Fsimage:NameNode內存中元數據序列化後造成的文件。 Edits:記錄客戶端更新元數據信息的每一步操做(可經過Edits運算出元數據)。 NameNode啓動時,先滾動Edits並生成一個空的edits.inprogress,而後加載Edits和Fsimage到內存中,此時NameNode內存就持有最新的元數據信息。Client開始對NameNode發送元數據的增刪改的請求,
這些請求的操做首先會被記錄到edits.inprogress中(查詢元數據的操做不會被記錄在Edits中,由於查詢操做不會更改元數據信息),若是此時NameNode掛掉,重啓後會從Edits中讀取元數據的信息。
而後,NameNode會在內存中執行元數據的增刪改的操做。因爲Edits中記錄的操做會愈來愈多,Edits文件會愈來愈大,致使NameNode在啓動加載Edits時會很慢,因此須要對Edits和Fsimage進行合併
(所謂合併,就是將Edits和Fsimage加載到內存中,照着Edits中的操做一步步執行,最終造成新的Fsimage)。SecondaryNameNode的做用就是幫助NameNode進行Edits和Fsimage的合併工做。
SecondaryNameNode首先會詢問NameNode是否須要CheckPoint(觸發CheckPoint須要知足兩個條件中的任意一個,定時時間到和Edits中數據寫滿了)。直接帶回NameNode是否檢查結果。
SecondaryNameNode執行CheckPoint操做,首先會讓NameNode滾動Edits並生成一個空的edits.inprogress,滾動Edits的目的是給Edits打個標記,之後全部新的操做都寫入edits.inprogress,
其餘未合併的Edits和Fsimage會拷貝到SecondaryNameNode的本地,而後將拷貝的Edits和Fsimage加載到內存中進行合併,生成fsimage.chkpoint,而後將fsimage.chkpoint拷貝給NameNode, 重命名爲Fsimage後替換掉原來的Fsimage。NameNode在啓動時就只須要加載以前未合併的Edits和Fsimage便可,由於合併過的Edits中的元數據信息已經被記錄在Fsimage中。

 Fsimage和Edits解析

 查看FsImage文件

[gll@hadoop101 current]$ ll
總用量 7256
-rw-rw-r--. 1 gll gll 1048576 1月  17 17:10 edits_0000000000000000001-0000000000000000001
-rw-rw-r--. 1 gll gll      42 1月  18 11:08 edits_0000000000000000002-0000000000000000003
-rw-rw-r--. 1 gll gll 1048576 1月  18 17:12 edits_0000000000000000004-0000000000000000020
-rw-rw-r--. 1 gll gll 1048576 1月  18 18:27 edits_0000000000000000021-0000000000000000021
-rw-rw-r--. 1 gll gll      42 1月  18 18:29 edits_0000000000000000022-0000000000000000023
-rw-rw-r--. 1 gll gll    3869 1月  18 19:29 edits_0000000000000000024-0000000000000000074
-rw-rw-r--. 1 gll gll     922 1月  18 20:29 edits_0000000000000000075-0000000000000000090
-rw-rw-r--. 1 gll gll 1048576 1月  18 20:37 edits_0000000000000000091-0000000000000000107
-rw-rw-r--. 1 gll gll      42 1月  19 11:28 edits_0000000000000000108-0000000000000000109
-rw-rw-r--. 1 gll gll      42 1月  19 12:28 edits_0000000000000000110-0000000000000000111
-rw-rw-r--. 1 gll gll      42 1月  19 13:28 edits_0000000000000000112-0000000000000000113
-rw-rw-r--. 1 gll gll    1276 1月  19 14:28 edits_0000000000000000114-0000000000000000127
-rw-rw-r--. 1 gll gll      42 1月  19 15:28 edits_0000000000000000128-0000000000000000129
-rw-rw-r--. 1 gll gll      42 1月  19 16:28 edits_0000000000000000130-0000000000000000131
-rw-rw-r--. 1 gll gll 1048576 1月  19 16:28 edits_0000000000000000132-0000000000000000132
-rw-rw-r--. 1 gll gll 1048576 1月  19 20:45 edits_0000000000000000133-0000000000000000133
-rw-rw-r--. 1 gll gll   14290 1月  20 12:24 edits_0000000000000000134-0000000000000000254
-rw-rw-r--. 1 gll gll      42 1月  20 13:24 edits_0000000000000000255-0000000000000000256
-rw-rw-r--. 1 gll gll      42 1月  20 14:24 edits_0000000000000000257-0000000000000000258
-rw-rw-r--. 1 gll gll 1048576 1月  20 14:24 edits_inprogress_0000000000000000259
-rw-rw-r--. 1 gll gll    2465 1月  20 13:24 fsimage_0000000000000000256
-rw-rw-r--. 1 gll gll      62 1月  20 13:24 fsimage_0000000000000000256.md5
-rw-rw-r--. 1 gll gll    2465 1月  20 14:24 fsimage_0000000000000000258
-rw-rw-r--. 1 gll gll      62 1月  20 14:24 fsimage_0000000000000000258.md5
-rw-rw-r--. 1 gll gll       4 1月  20 14:24 seen_txid
-rw-rw-r--. 1 gll gll     206 1月  20 11:36 VERSION
[gll@hadoop101 current]$ 
[gll@hadoop101 current]$ cat seen_txid  //文件保存的是一個數字,就是最後一個edit_數字

[gll@hadoop101 current]$ hdfs oiv -p XML -i fsimage_0000000000000000258 -o /opt/module/hadoop-2.7.2/fsimage.xml
[gll@hadoop101 current]$ sz /opt/module/hadoop-2.7.2/fsimage.xml

CheckPoint時間設置

1)一般狀況下,SecondaryNameNode每隔一小時執行一次。

2)一分鐘檢查一次操做次數;

3 )當操做次數達到1百萬時,SecondaryNameNode執行一次。

NameNode故障處理

方法一:將SecondaryNameNode數據拷貝到NameNode存儲數據的目錄:可是這樣處理,2nn的數據有部分沒有合併,會不全,數據丟失。

1. kill -9 NameNode進程

2. 刪除NameNode存儲的數據(/opt/module/hadoop-2.7.2/data/tmp/dfs/name)

[atguigu@hadoop102 hadoop-2.7.2]$ rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

3. 拷貝SecondaryNameNode中數據到原NameNode存儲數據目錄

[atguigu@hadoop102 dfs]$ scp -r atguigu@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary/* ./name/

4. 從新啓動NameNode

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start namenode

方法二:使用-importCheckpoint選項啓動NameNode守護進程,從而將SecondaryNameNode中數據拷貝到NameNode目錄

1.修改hdfs-site.xml中的
<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>120</value>
</property>
<property>
  <name>dfs.namenode.name.dir</name>
  <value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value>
</property>

2.  kill -9 NameNode進程

3. 刪除NameNode存儲的數據(/opt/module/hadoop-2.7.2/data/tmp/dfs/name)

[atguigu@hadoop102 hadoop-2.7.2]$ rm -rf /opt/module/hadoop-2.7.2/data/tmp/dfs/name/*

4. 若是SecondaryNameNode不和NameNode在一個主機節點上,須要將SecondaryNameNode存儲數據的目錄拷貝到NameNode存儲數據的平級目錄,並刪除in_use.lock文件

[atguigu@hadoop102 dfs]$ scp -r atguigu@hadoop104:/opt/module/hadoop-2.7.2/data/tmp/dfs/namesecondary ./

[atguigu@hadoop102 namesecondary]$ rm -rf in_use.lock

[atguigu@hadoop102 dfs]$ pwd

/opt/module/hadoop-2.7.2/data/tmp/dfs

[atguigu@hadoop102 dfs]$ ls

data  name  namesecondary

5. 導入檢查點數據(等待一會ctrl+c結束掉)

[atguigu@hadoop102 hadoop-2.7.2]$ bin/hdfs namenode -importCheckpoint

6. 啓動NameNode

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start namenode

集羣安全模式

集羣處於安全模式,不能執行重要操做(寫操做)。集羣啓動完成後,自動退出安全模式。
(1)bin/hdfs dfsadmin -safemode get     (功能描述:查看安全模式狀態)
(2)bin/hdfs dfsadmin -safemode enter   (功能描述:進入安全模式狀態)
(3)bin/hdfs dfsadmin -safemode leave   (功能描述:離開安全模式狀態)
(4)bin/hdfs dfsadmin -safemode wait    (功能描述:等待安全模式狀態)

DataNode工做機制

1一個數據塊在DataNode上以文件形式存儲在磁盤上,包括兩個文件,一個是數據自己,一個是元數據包括數據塊的長度,塊數據校驗和,以及時間戳

2DataNode啓動後向NameNode註冊,經過後,週期性(1小時NameNode上報全部的塊信息。

3心跳是每3一次,心跳返回結果帶有NameNode給該DataNode的命令如複製塊數據到另外一臺機器,或刪除某個數據塊若是超過10分鐘沒有收到某個DataNode的心跳,則認爲該節點不可用。

4集羣運行中能夠安全加入和退出一些機器

DataNode數據完整性

1當DataNode讀取Block的時候,它會計算CheckSum

2若是計算後的CheckSum,與Block建立時值不同,說明Block已經損壞。

3Client讀取其餘DataNode上的Block

4DataNode在其文件建立後周期驗證CheckSum,如圖3-16所示。

 DataNode掉線時限參數設置

 服役新數據節點

隨着公司業務的增加,數據量愈來愈,原有的數據節點的容量已經不能知足存儲數據的需求,須要在原有集羣基礎上動態添加的數據節點

1. 環境準備

1)在hadoop104主機克隆一臺hadoop105主機

2)修改IP地址和主機名稱

(3)刪除原來HDFS文件系統留存的文件/opt/module/hadoop-2.7.2/datalog

4source一下配置文件

[atguigu@hadoop105 hadoop-2.7.2]$ source /etc/profile

2. 服役新節點具體步驟

(1)直接啓動DataNode便可關聯到集羣

[atguigu@hadoop105 hadoop-2.7.2]$ sbin/hadoop-daemon.sh start datanode

[atguigu@hadoop105 hadoop-2.7.2]$ sbin/yarn-daemon.sh start nodemanager

(2)在hadoop105上上傳文件

[atguigu@hadoop105 hadoop-2.7.2]$ hadoop fs -put /opt/module/hadoop-2.7.2/LICENSE.txt /

3)若是數據不均衡,能夠用命令實現集羣的再平衡

[atguigu@hadoop102 sbin]$ ./start-balancer.sh

starting balancer, logging to /opt/module/hadoop-2.7.2/logs/hadoop-atguigu-balancer-hadoop102.out

退役舊數據節點

添加白名單

添加到白名單的主機節點都容許訪問NameNode不在白名單的主機節點,都會退出。

配置白名單的具體步驟以下:

1)在NameNode的/opt/module/hadoop-2.7.2/etc/hadoop目錄下建立dfs.hosts文件 [atguigu@hadoop102 hadoop]$ pwd
 /opt/module/hadoop-2.7.2/etc/hadoop [atguigu@hadoop102 hadoop]$ touch dfs.hosts [atguigu@hadoop102 hadoop]$ vi dfs.hosts 添加以下主機名稱(不添加hadoop105) hadoop102 hadoop103 hadoop104 (2)在NameNode的hdfs-site.xml配置文件中增長dfs.hosts屬性  <property>
 <name>dfs.hosts</name>
 <value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts</value>
 </property>3)配置文件分發 [atguigu@hadoop102 hadoop]$ xsync hdfs-site.xml (4)刷新NameNode [atguigu@hadoop102 hadoop-2.7.2]$ hdfs dfsadmin -refreshNodes Refresh nodes successful (5)更新ResourceManager節點 [atguigu@hadoop102 hadoop-2.7.2]$ yarn rmadmin -refreshNodes  17/06/24 14:17:11 INFO client.RMProxy: Connecting to ResourceManager at hadoop103/192.168.1.103:8033

黑名單退役

黑名單上面的主機都會被強制退出

1.NameNode的/opt/module/hadoop-2.7.2/etc/hadoop目錄建立dfs.hosts.exclude文件

[atguigu@hadoop102 hadoop]$ pwd
/opt/module/hadoop-2.7.2/etc/hadoop [atguigu@hadoop102 hadoop]$ touch dfs.hosts.exclude [atguigu@hadoop102 hadoop]$ vi dfs.hosts.exclude 添加以下主機名稱(要退役的節點) hadoop105

2.在NameNodehdfs-site.xml配置文件中增長dfs.hosts.exclude屬性

<property>
<name>dfs.hosts.exclude</name>
      <value>/opt/module/hadoop-2.7.2/etc/hadoop/dfs.hosts.exclude</value>
</property>

3.刷新NameNode、刷新ResourceManager

[atguigu@hadoop102 hadoop-2.7.2]$ hdfs dfsadmin -refreshNodes Refresh nodes successful [atguigu@hadoop102 hadoop-2.7.2]$ yarn rmadmin -refreshNodes 17/06/24 14:55:56 INFO client.RMProxy: Connecting to ResourceManager at hadoop103/192.168.1.103:8033

4. 檢查Web瀏覽器,退役節點的狀態爲decommission in progress(退役),說明數據節點正在複製塊到其餘節點,如圖3-17所示

5.等待退役節點狀態decommissioned(全部塊已經複製完成),中止該節點及節點資源管理器。注意:若是副本數是3服役的節點小於等於3,是不能退役成功的,須要修改副本數後才能退役,如圖3-18所示

[atguigu@hadoop105 hadoop-2.7.2]$ sbin/hadoop-daemon.sh stop datanode stopping datanode [atguigu@hadoop105 hadoop-2.7.2]$ sbin/yarn-daemon.sh stop nodemanager stopping nodemanager

6. 若是數據不均衡,能夠用命令實現集羣的再平衡

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/start-balancer.sh starting balancer, logging to /opt/module/hadoop-2.7.2/logs/hadoop-atguigu-balancer-hadoop102.out Time Stamp Iteration# Bytes Already Moved Bytes Left To Move Bytes Being Moved

注意不容許白名單和黑名單同時出現同一個主機名稱

DataNode多級目錄配置

1. DataNode也能夠配置成多個目錄,每一個目錄存儲的數據不同。:數據不是副本

2.具體配置以下

hdfs-site.xml <property>
        <name>dfs.datanode.data.dir</name>
<value>file:///${hadoop.tmp.dir}/dfs/data1,file:///${hadoop.tmp.dir}/dfs/data2</value>
</property>

HDFS2.x新特性

集羣間數據拷貝

1.scp實現兩個遠程主機之間的文件複製 scp -r hello.txt root@hadoop103:/user/atguigu/hello.txt // 推 push scp -r root@hadoop103:/user/atguigu/hello.txt hello.txt // 拉 pull scp -r root@hadoop103:/user/atguigu/hello.txt root@hadoop104:/user/atguigu //是經過本地主機中轉實現兩個遠程主機的文件複製;若是在兩個遠程主機之間ssh沒有配置的狀況下可使用該方式。 2.採用distcp命令實現兩個Hadoop集羣之間的遞歸數據複製 [atguigu@hadoop102 hadoop-2.7.2]$ bin/hadoop distcp hdfs://haoop102:9000/user/atguigu/hello.txt hdfs://hadoop103:9000/user/atguigu/hello.txt

小文件存檔

案例實操

(1)須要啓動YARN進程
[atguigu@hadoop102 hadoop-2.7.2]$ start-yarn.sh

(2)歸檔文件
把/user/atguigu/input目錄裏面的全部文件歸檔成一個叫input.har的歸檔文件,並把歸檔後文件存儲到/user/atguigu/output路徑下。
[atguigu@hadoop102 hadoop-2.7.2]$ bin/hadoop archive -archiveName input.har –p  /user/atguigu/input   /user/atguigu/output

(3)查看歸檔
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -lsr /user/atguigu/output/input.har
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -lsr har:///user/atguigu/output/input.har

(4)解歸檔文件
[atguigu@hadoop102 hadoop-2.7.2]$ hadoop fs -cp har:/// user/atguigu/output/input.har/*    /user/atguigu

 HDFS HA高可用

HA概述

1)所謂HA(High Available),即高可用(7*24小時中段服務)

2)實現高可用最關鍵策略是消除單點故障。HA嚴格來講應該分紅各個組件的HA機制HDFSHAYARNHA

3)Hadoop2.0以前,在HDFS集羣中NameNode存在單點故障(SPOF

4) NameNode主要在如下兩個方面影響HDFS集羣

  •    NameNode機器發生意外,如宕機,集羣將沒法使用,直到管理員重啓
  •    NameNode機器須要升級,包括軟件、硬件升級,此時集羣也將沒法使用 

HDFS HA功能經過配置Active/Standby兩個NameNodes實現在集羣中對NameNode的熱備來解決上述問題。若是出現故障,如機器崩潰或機器須要升級維護,這時可經過此種方式將NameNode很快的切換到另一臺機器。

 HDFS-HA工做機制

經過雙NameNode消除單點故障

 HDFS-HA工做要點

1. 元數據管理方式須要改變

內存中各自保存一份元數據;

Edits日誌只有Active狀態的NameNode節點能夠作寫操做;

兩個NameNode均可以讀取Edits

共享的Edits放在一個共享存儲中管理qjournalNFS兩個主流實現);

2. 須要一個狀態管理功能模塊

實現了一個zkfailover,常駐在每個namenode所在的節點,每個zkfailover負責監控本身所在NameNode節點,利用zk進行狀態標識,當須要進行狀態切換時,由zkfailover來負責切換,切換時須要防止brain split現象的發生。

3. 必須保證兩個NameNode之間可以ssh無密碼登陸

4. 隔離Fence同一時刻僅僅有一個NameNode對外提供服務

 HDFS-HA自動故障轉移機制  

故障轉移增長了zookeeper和ZKFS進程

Zookeeper:維護少許協調數據,通知客戶端這些數據的改變和監視客戶端故障的高可用服務

HA依賴zookeeper的一下功能:

1故障檢測:集羣中的每一個NameNodeZooKeeper中維護了一個持久會話,若是機器崩潰,ZooKeeper中的會話將終止,ZooKeeper通知另外一個NameNode須要觸發故障轉移。

2現役NameNode選擇:ZooKeeper提供了一個簡單的機制用於惟一的選擇一個節點爲active狀態。若是目前現役NameNode崩潰,另外一個節點可能從ZooKeeper得到特殊的排外鎖以代表它應該成爲現役NameNode

ZKFC是自動故障轉移中的另外一個新組件,是ZooKeeper的客戶端,也監視和管理NameNode的狀態。每一個運行NameNode的主機也運行了一個ZKFC進程,ZKFC負責:

1健康監測:ZKFC使用一個健康檢查命令按期地ping與之在相同主機的NameNode,只要該NameNode及時地回覆健康狀態,ZKFC認爲該節點是健康的。若是該節點崩潰,凍結或進入不健康狀態,健康監測器標識該節點爲非健康的。

2ZooKeeper會話管理:當本地NameNode是健康的,ZKFC保持一個在ZooKeeper中打開的會話。若是本地NameNode處於active狀態,ZKFC也保持一個特殊的znode鎖,該鎖使用了ZooKeeper對短暫節點的支持,若是會話終止,鎖節點將自動刪除。

3基於ZooKeeper的選擇:若是本地NameNode是健康的,且ZKFC發現沒有其它的節點當前持有znode鎖,它將爲本身獲取該鎖。若是成功,則它已經贏得了選擇,並負責運行故障轉移進程以使它的本地NameNodeActive。故障轉移進程與前面描述的手動故障轉移類似,首先若是必要保護以前的現役NameNode,而後本地NameNode轉換爲Active狀態。

 

 ZKFC:是zookeeper的客戶端,讓它聯繫zookeeper,HA是hadoop2.0纔有的,namenode在1.0時就有了,可是爲了保持NameNode的健壯性,未把ZKFC加入NameNode中,可是兩個進程是相互綁定的,有ZKFC監視NameNode,

將狀態彙報給zookeeper。

主Namenode處理全部的操做請求(讀寫),而Standby只是做爲slave,維護儘量同步的狀態,使得故障時可以快速切換到Standby。爲了使Standby Namenode與Active Namenode數據保持同步,兩個Namenode都與一組Journal Node進行通訊。當主Namenode進行任務的namespace操做時,都會確保持久會修改日誌到Journal Node節點中的大部分。Standby Namenode持續監控這些edit,當監測到變化時,將這些修改應用到本身的namespace

當進行故障轉移時,Standby在成爲Active Namenode以前,會確保本身已經讀取了Journal Node中的全部edit日誌,從而保持數據狀態與故障發生前一致。

腦裂現象(split brain): 當兩臺Namenode都認爲本身的Active Namenode時,會同時嘗試寫入數據(不會再去檢測和同步數據):zookeeper會根據自身通知機制,確認主機,防止腦裂。

若是一臺出現了假死,當前NameNode監控的ZKFX檢測到假死,會通知從機的ZKFC,從而殺死假死的NameNode的進程,激活從機爲Active,同時通知zookeeper服務端將從機註冊爲Active。

如今合併fsimage是由standby來完成的,沒有secondaryNameNode;

Journal Nodes爲了防止腦裂,只讓一個Namenode寫入數據,內部經過維護epoch數來控制,從而安全地進行故障轉移,有兩種方式共享edits log:

  • 使用NFS共享edit log(存儲在NAS/SAN)

     

如圖所示,NFS做爲主備Namenode的共享存儲。這種方案可能會出現腦裂(split-brain),即兩個節點都認爲本身是主Namenode並嘗試向edit log寫入數據,這可能會致使數據損壞。經過配置fencin腳原本解決這個問題,fencing腳本用於:

將以前的Namenode關機
禁止以前的Namenode繼續訪問共享的edit log文件
使用這種方案,管理員就能夠手工觸發Namenode切換,而後進行升級維護。但這種方式存在如下問題:
- 只能手動進行故障轉移,每次故障都要求管理員採起措施切換。
- NAS/SAN設置部署複雜,容易出錯,且NAS自己是單點故障。
- Fencing 很複雜,常常會配置錯誤。
- 沒法解決意外(unplanned)事故,如硬件或者軟件故障。

所以須要另外一種方式來處理這些問題:

  1. 自動故障轉移(引入ZooKeeper達到自動化)
  2. 移除對外界軟件硬件的依賴(NAS/SAN)
  3. 同時解決意外事故及平常維護致使的不可用
  • 使用QJM共享edit log:Quorum-based 存儲 + ZooKeeper

QJM(Quorum Journal Manager)是Hadoop專門爲Namenode共享存儲開發的組件。其集羣運行一組Journal Node,每一個Journal 節點暴露一個簡單的RPC接口,容許Namenode讀取和寫入數據,數據存放在Journal節點的本地磁盤。當Namenode寫入edit log時,它向集羣的全部Journal Node發送寫入請求,當多數節點回復確認成功寫入以後,edit log就認爲是成功寫入。例若有3個Journal Node,Namenode若是收到來自2個節點的確認消息,則認爲寫入成功。
而在故障自動轉移的處理上,引入了監控Namenode狀態的ZookeeperFailController(ZKFC)。ZKFC通常運行在Namenode的宿主機器上,與Zookeeper集羣協做完成故障的自動轉移。整個集羣架構圖以下:

Namenode使用QJM 客戶端提供的RPC接口與Namenode進行交互。寫入edit log時採用基於仲裁的方式,即數據必須寫入JournalNode集羣的大部分節點。

在Journal Node節點上(服務端)

服務端Journal運行輕量級的守護進程,暴露RPC接口供客戶端調用。實際的edit log數據保存在Journal Node本地磁盤,該路徑在配置中使用dfs.journalnode.edits.dir屬性指定。

Journal Node經過epoch數來解決腦裂的問題,稱爲JournalNode fencing。具體工做原理以下:
1)當Namenode變成Active狀態時,被分配一個整型的epoch數,這個epoch數是獨一無二的,而且比以前全部Namenode持有的epoch number都高。

2)當Namenode向Journal Node發送消息的時候,同時也帶上了epoch。當Journal Node收到消息時,將收到的epoch數與存儲在本地的promised epoch比較,若是收到的epoch比本身的大,則使用收到的epoch更新本身本地的epoch數。若是收到的比本地的epoch小,則拒絕請求。

3)edit log必須寫入大部分節點纔算成功,也就是其epoch要比大多數節點的epoch高。

 

這種方式解決了NFS方式的3個問題:

不須要額外的硬件,使用原有的物理機
Fencing經過epoch數來控制,避免出錯。
自動故障轉移:Zookeeper處理該問題。
HDFS-HA故障轉移參考:http://www.javashuo.com/article/p-xlfrzyaa-ca.html

HDFS-HA集羣配置

環境準備

1. 修改IP

2. 修改主機名及主機名和IP地址的映射

3. 關閉防火牆

4. ssh免密登陸

5. 安裝JDK,配置環境變量等

規劃集羣

hadoop102  

hadoop103  

hadoop104

NameNode

NameNode

 

JournalNode

JournalNode

JournalNode

DataNode

DataNode

DataNode

ZK

ZK

ZK

 

ResourceManager

 

NodeManager

NodeManager

NodeManager 

 

配置HDFS-HA集羣

在opt目錄下建立一個ha文件夾 mkdir ha
/opt/app/下的 hadoop-2.7.2拷貝到/opt/ha目錄下 cp -r hadoop-2.7.2/ /opt/ha/
配置hadoop-env.sh export JAVA_HOME=/opt/module/jdk1.8.0_144

配置core-site.xml

<configuration>
<!-- 把兩個NameNode)的地址組裝成一個集羣mycluster -->
        <property>
            <name>fs.defaultFS</name>
            <value>hdfs://mycluster</value>
        </property>

        <!-- 指定hadoop運行時產生文件的存儲目錄 -->
        <property>
            <name>hadoop.tmp.dir</name>
            <value>/opt/ha/hadoop-2.7.2/data/tmp</value>
        </property>
</configuration>

配置hdfs-site.xml

<configuration>
    <!-- 徹底分佈式集羣名稱 -->
    <property>
        <name>dfs.nameservices</name>
        <value>mycluster</value>
    </property>

    <!-- 集羣中NameNode節點都有哪些 -->
    <property>
        <name>dfs.ha.namenodes.mycluster</name>
        <value>nn1,nn2</value>
    </property>

    <!-- nn1的RPC通訊地址 -->
    <property>
        <name>dfs.namenode.rpc-address.mycluster.nn1</name>
        <value>hadoop102:9000</value>
    </property>

    <!-- nn2的RPC通訊地址 -->
    <property>
        <name>dfs.namenode.rpc-address.mycluster.nn2</name>
        <value>hadoop103:9000</value>
    </property>

    <!-- nn1的http通訊地址 -->
    <property>
        <name>dfs.namenode.http-address.mycluster.nn1</name>
        <value>hadoop102:50070</value>
    </property>

    <!-- nn2的http通訊地址 -->
    <property>
        <name>dfs.namenode.http-address.mycluster.nn2</name>
        <value>hadoop103:50070</value>
    </property>

    <!-- 指定NameNode元數據在JournalNode上的存放位置 -->
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
    <value>qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/mycluster</value>
    </property>

    <!-- 配置隔離機制,即同一時刻只能有一臺服務器對外響應 -->
    <property>
        <name>dfs.ha.fencing.methods</name>
        <value>sshfence</value>
    </property>

    <!-- 使用隔離機制時須要ssh無祕鑰登陸-->
    <property>
        <name>dfs.ha.fencing.ssh.private-key-files</name>
        <value>/home/atguigu/.ssh/id_rsa</value>
    </property>

    <!-- 聲明journalnode服務器存儲目錄-->
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/opt/ha/hadoop-2.7.2/data/jn</value>
    </property>

    <!-- 關閉權限檢查-->
    <property>
        <name>dfs.permissions.enable</name>
        <value>false</value>
    </property>

    <!-- 訪問代理類:client,mycluster,active配置失敗自動切換實現方式-->
    <property>
          <name>dfs.client.failover.proxy.provider.mycluster</name>
    <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
    </property>
</configuration>

拷貝配置好的hadoop環境到其餘節點

啓動HDFS-HA集羣

1. 在各個JournalNode節點上,輸入如下命令啓動journalnode服務 sbin/hadoop-daemon.sh start journalnode 2. 在[nn1]上,對其進行格式化,並啓動 bin/hdfs namenode -format sbin/hadoop-daemon.sh start namenode 3. 在[nn2]上,同步nn1的元數據信息 bin/hdfs namenode -bootstrapStandby 4. 啓動[nn2] sbin/hadoop-daemon.sh start namenode 5. 在[nn1]上,啓動全部datanode sbin/hadoop-daemons.sh start datanode 6. 將[nn1]切換爲Active bin/hdfs haadmin -transitionToActive nn1 7. 查看是否Active bin/hdfs haadmin -getServiceState nn1

配置HDFS-HA自動故障轉移

 1. 具體配置

1)在hdfs-site.xml中增長

<property>
    <name>dfs.ha.automatic-failover.enabled</name>
    <value>true</value>
</property>

2)在core-site.xml文件中增長

<property>
    <name>ha.zookeeper.quorum</name>
    <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>

 2. 啓動

(1)關閉全部HDFS服務: sbin/stop-dfs.sh (2)啓動Zookeeper集羣: bin/zkServer.sh start (3)初始化HA在Zookeeper中狀態: bin/hdfs zkfc -formatZK (4)啓動HDFS服務: sbin/start-dfs.sh 
3.驗證
1)將Active NameNode進程kill  kill -9 namenode的進程id
2)將Active NameNode機器斷開網絡 service network stop

YARN-HA配置

YARN-HA工做機制,如圖3-23所示:

具體配置

1yarn-site.xml

<configuration>
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>
    <!--啓用resourcemanager ha-->
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>
    <!--聲明兩臺resourcemanager的地址-->
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>cluster-yarn1</value>
    </property>
    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>hadoop102</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>hadoop103</value>
    </property>
    <!--指定zookeeper集羣的地址--> 
    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
    </property>
    <!--啓用自動恢復--> 
    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>
    <!--指定resourcemanager的狀態信息存儲在zookeeper集羣--> 
    <property>
        <name>yarn.resourcemanager.store.class</name>    
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> </property> </configuration>

啓動hdfs 

1)在各個JournalNode節點上,輸入如下命令啓動journalnode服務: sbin/hadoop-daemon.sh start journalnode (2)在[nn1]上,對其進行格式化,並啓動: bin/hdfs namenode -format sbin/hadoop-daemon.sh start namenode (3)在[nn2]上,同步nn1的元數據信息: bin/hdfs namenode -bootstrapStandby (4)啓動[nn2]: sbin/hadoop-daemon.sh start namenode (5)啓動全部DataNode sbin/hadoop-daemons.sh start datanode (6)將[nn1]切換爲Active bin/hdfs haadmin -transitionToActive nn1

啓動YARN 

1)在hadoop102中執行: sbin/start-yarn.sh2)在hadoop103中執行: sbin/yarn-daemon.sh start resourcemanager (3)查看服務狀態,如圖3-24所示 bin/yarn rmadmin -getServiceState rm1
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息