hdfs高可用搭建
搭建HDFS高可用
在搭建hdfs高可用過程中,以node1、node2和node3來搭建高可用環境,每個節點所分配的作用如表4.3所示。
由表4.3中可以看出,NameNode(NN)分別配置在node1和node2上,ZKFC配置在node1和node3上,JournalNode(JN)配置在node1、node2和node3上,ZooKeeper(ZK)配置在node1、node2和node3上,DataNode(DN)配置在node1、node2和node3上。接下來開始高可用的搭建,首先來配置ZooKeeper。
配置ZooKeeper
首先從官網http://zookeeper.apache.org/下載ZooKeeper,這裡以ZooKeeper-3.4.13為例,並上傳到node1上。
解壓縮ZooKeeper:
tar -zvxf ../appinstall/zookeeper-3.4.13.tar.gz
在ZooKeeper-3.4.13的conf資料夾下建立zoo.cfg檔案並寫入以下配置:
tickTime=2000 initLimit=5 syncLimit=2 dataDir=/opt/Zookeeper/data clientPort=2181 server.1=node1:2888:3888 server.2=node2:2888:3888 server.3=node3:2888:3888
其中,dataDir代表存放ZooKeeper資料檔案的目錄,server.1、server.2和server.3中的1、2、3分別對應第1個節點、第2個節點和第3個節點,其中2888和3888代表接收和傳送資料的埠。
建立myid,為了保障server.1、server.2和server.3,可以分別和第1個節點(node1)、第2個節點(node2)和第3個節點(node3)對應起來,還需要在dataDir所對應的資料夾中建立myid檔案。具體操作如下。
在node1節點上建立/opt/ZooKeeper/data資料夾,並在其中建立myid檔案。
接著在myid檔案中寫入1,這樣就和server.1對應起來了。通過more myid命令可以檢視myid檔案中的內容。
在node2和node3中的/opt/ZooKeeper/data下分別建立myid檔案,並分別寫入2和3,此處與node1操作類似,寫入後分別通過more檢視檔案內容。
複製node1上的ZooKeeper到node2和node3節點上。
啟動ZooKeeper。進入每個節點的ZooKeeper的bin目錄並啟動ZooKeeper,啟動命令如下:
注意:每個節點都要單獨啟動
檢查ZooKeeper是否配置成功,在每個節點輸入jps命令檢視程序,會發現有個QuorumPeerMain,這就是ZooKeeper的程序
這樣就代表ZooKeeper叢集已經配置成功。
配置Hadoop配置檔案
Hadoop配置檔案一共有4個,分別是:
hadoop-env.sh的配置,是關於Hadoop執行環境的配置,在配置高可用時,分別定義了JAVA_HOME及執行NameNode、DataNode、ZKFC和JournalNode程序的使用者:
export JAVA_HOME=/app/jdk1.8.0_211
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_ZKFC_USER=root
export HDFS_JOURNALNODE_USER=root
core-site.xml檔案的配置如下:
<configuration> <!--預設檔案系統名稱--> <property> <name>fs.defaultFS</name> <value>hdfs://mycluster</value> </property> <!--HDFS檔案系統的元資訊儲存目錄--> <property> <name>hadoop.tmp.dir</name> <value>/opt/hadoopdata</value> </property> <!--定義在網頁介面訪問資料時使用的使用者名稱--> <property> <name>hadoop.http.staticuser.user</name> <value>root</value> </property> <!--故障轉移需要的zookeeper叢集--> <property> <name>ha.zookeeper.quorum</name> <value>node1:2181,node2:2181,node3:2181</value> </property> </configuration>
其中,hadoop.http.staticuser.user是定義在網頁介面訪問資料時使用的使用者名稱,ha.zookeeper.quorum是定義ZooKeeper叢集(注意zookeeper要小寫)。
hdfs-site.xml檔案的配置如下:
<configuration> <!--完全分散式叢集名稱,和core-site叢集名稱必須一致--> <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>node1:8020</value> </property> <!--nn2的RPC通訊地址--> <property> <name>dfs.namenode.rpc-address.mycluster.nn2</name> <value>node2:8020</value> </property> <!--nn1的http通訊地址--> <property> <name>dfs.namenode.http-address.mycluster.nn1</name> <value>node1:9870</value> </property> <!--nn2的http通訊地址--> <property> <name>dfs.namenode.http-address.mycluster.nn2</name> <value>node2:9870</value> </property> <!--指定NameNode元資料在JournalNode上的存放位置--> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://node1:8485;node2:8485;node3:8485/wen</value> </property> <!--客戶端與活動狀態的NameNode 進行互動的 Java 實現類--> <property> <name>dfs.client.failover.proxy.provider.mycluster</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</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>/root/.ssh/id_rsa</value> </property> <!--宣告journalnode伺服器儲存目錄--> <property> <name>dfs.journalnode.edits.dir</name> <value>/opt/journalnode/data</value> </property> <!--故障自動轉移設定為true--> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> <!--設定為false可以不用檢查許可權--> <property> <name>dfs.permission</name> <value>false</value> </property> </configuration>
其中,dfs.nameservices是配置HDFS叢集ID,dfs.ha.namenodes.mycluster是配置NameNode的ID號,dfs.namenode.rpc-address.mycluster.nn1是定義NameNode的主機名和RPC協議的埠,dfs.namenode.http-address.mycluster.nn1是定義NameNode的主機名和HTTP協議的埠。
dfs.namenode.shared.edits.dir是定義共享edits的URL,dfs.client.failover.proxy.provider.mycluster是定義返回active namenode的類。
dfs.ha.fencing.methods是定義NameNode切換時的隔離方法,主要是為了防止“腦裂”問題,dfs.ha.fencing.ssh.private-key-files是定義隔離方法的金鑰,dfs.journalnode.edits.dir是儲存edits檔案的目錄,dfs.ha.automatic-failover.enabled用於定義開啟自動切換。
workers檔案的配置如下:
node1
node2
node3
workers主要配置DataNode節點,在workers配置檔案中寫入以上內容,代表node1、node2和node3是DataNode節點。
將配置檔案複製到其他節點上
scp ./hadoop-env.sh root@node2:/app/hadoop-3.2.1/etc/hadoop/
scp ./hadoop-env.sh root@node3:/app/hadoop-3.2.1/etc/hadoop/
scp ./core-site.xml root@node3:/app/hadoop-3.2.1/etc/hadoop/
scp ./core-site.xml root@node2:/app/hadoop-3.2.1/etc/hadoop/
scp ./hdfs-site.xml root@node2:/app/hadoop-3.2.1/etc/hadoop/
scp ./hdfs-site.xml root@node3:/app/hadoop-3.2.1/etc/hadoop/
scp ./workers root@node2:/app/hadoop-3.2.1/etc/hadoop/
scp ./workers root@node3:/app/hadoop-3.2.1/etc/hadoop/
啟動JN節點
啟動JN節點,命令如下:
hdfs --daemon start journalnode
在node1、node2和node3上分別啟動JournalNode,然後通過jps命令進行檢視,這裡以node1為例。程式碼如下:
格式化,在node1上執行格式化操作,執行命令如下:
hdfs namenode -format
複製元資料到node2節點上
由於我們需要把node1和node2設定為兩個NameNode,所以搭建高可用時要求node1和node2上的元資料是一樣的,因此需要將node1上的元資料複製到node2上。在這裡需要注意的是,執行格式化命令後,會在/opt/hadoopdata目錄下生成元資料,執行命令如下:
scp -r /opt/hadoopdata root@node2:/opt/
格式化ZKFC
ZKFC(ZooKeeper Failover Controller)是在HDFS高可用前提下,基於ZooKeeper的自動切換原理觸發NameNode切換的一個程序。
在NameNode節點上啟動的ZKFC程序內部,執行著如下3個物件服務。
·HealthMonitor:定期檢查NameNode是否不可用或是否進入了一個不健康的狀態,並及時通知ZooKeeper Failover Controller。
·ActiveStandbyElector:控制和監控NameNode在ZooKeeper上的狀態。
·ZKFailoverController:協調HealthMonitor和ActiveStandbyElector物件並處理它們通知的event變化事件,完成自動切換的過程。
通hdfs zkfc -formatZK 命令格式化ZKFC(ZooKeeper Failover Controller),執行命令如下:
啟動ZKF,hdfs --daemon start zkfc ,啟動後jps,DFSZKFailoverController程序啟動表示成功,如下表示啟動成功(若namenode2沒有啟動成功,可在namenode2手動啟動zkfc)
啟動叢集
執行start-dfs.sh命令啟動叢集:
從上面的提示中可以看出node1和node2作為HDFS高可用的NameNode,node1、node2和node3作為用來保證NameNode間資料共享的JournalNode。
通過瀏覽器檢視叢集狀態
在瀏覽器中分別開啟http://192.168.10.11:9870/和http://192.168.10.12:9870/,會看到下面兩個介面,可以看出node2為active狀態,node1是standby狀態,如圖所示。
高可用測試
目前node1是standby(備用)狀態,node2是active(活躍)狀態,現在我們先檢視NameNode程序的ID號,隨後殺死在node2中處於active狀態的NameNode程序,測試當此節點失效時,備用NameNode(即node1)能否接管已失效節點的任務並開始服務於來自客戶端的請求,命令如下:
接著我們開啟node1,發現node1的狀態已經變成了active狀態,如圖4.12所示。這樣,關於Hadoop 3的高可用就配置成功了。關於高可用的配置,讀者可以參考官網http://hadoop.apache.org/docs/r3.1.0/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailability WithQJM.html。