環境
- CentOS 7
- JAVA 1.8
- Zookeeper 2.9.2
- Hadoop 3.4.14
一、簡單HDFS叢集中存在的問題及解決辦法
-
如何解決NameNode的單節點問題
多個NameNode備份原NameNode資料
-
如何解決多個NameNode是叢集腦裂問題
使用QJM,
是Hadoop專門為Namenode共享存儲開發的元件。其叢集運作一組QJM(Quorum Journal Manager)
,每個Journal 節點暴露一個簡單的RPC接口,允許Namenode讀取和寫入資料,資料存放在Journal節點的本地磁盤。當Namenode寫入Journal Node
edit log
時,它向叢集的所有Journal Node發送寫入請求,當多數節點回複确認成功寫入之後,edit log就認為是成功寫入。例如有3個Journal Node,Namenode如果收到來自2個節點的确認消息,則認為寫入成功。
而在故障自動轉移的處理上,引入了監控Namenode狀态的ZookeeperFailController(ZKFC)。ZKFC一般運作在Namenode的主控端器上,與Zookeeper叢集協作完成故障的自動轉移。整個叢集架構圖如下:
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-Qcs6IyNJ-1590331418486)(/images/HDFS高可用叢集搭建/SouthEast.png)]
- 在HA叢集中如何ZK與
出現網絡延遲問題這種情況,ZK會自動将NameNode active
NameNode standby
切換為活躍節點,這個時候就出現了多個active節點,也就意味着現有叢集面臨腦裂問題
使用JournalNode
- 負責NameNode的edit log同步
- JournalNode隔離機制,保證在一個時刻隻有一個NameNode active,使用ssh登入到NameNode節點使用kill指令殺死NameNode。
二、叢集規劃
1. 相關要求:
- 節點個數最好是奇數個 3個節點
- 每個zookeeper服務會啟動至少三個端口
- 1.client處理
- 2.内部資料原子廣播
- 3.内部選舉投票端口
2. 伺服器相關資訊
hostname | 所運作服務 | IP位址 |
---|---|---|
zk1 | zkNode1 | 按照實際IP位址 |
zk2 | zkNode2 | 按照實際IP位址 |
zk3 | zkNode3 | 按照實際IP位址 |
hadoop1 | NameNode(active) & DataNode & JournalNode & ZKFC | 按照實際IP位址 |
hadoop2 | NameNode(standby) & DataNode & JournalNode & ZKFC | 按照實際IP位址 |
hadoop3 | DataNode & JournalNode & ZKFC | 按照實際IP位址 |
3. 共同配置
(1) 修改所有機器hostname
vi /etc/hostname
(2) 配置hosts檔案,将ip位址與主機名進行映射
vi /etc/hosts
(3) 重新開機機器
(4) 配置ssh免密登入,實作start-dfs.sh執行的機器可以免密登入其他的NameNode和DataNode節點
1. hadoop1: ssh-keygen -t -rsa
2. hadoop1: ssh-copy-id hadoop1
3. hadoop1: ssh-copy-id hadoop2
4. hadoop1: ssh-copy-id hadoop3
(5) 配置JAVA環境
(6) 修改環境變量
#進入配置檔案
vi /etc/profile
# 添加如下配置
export JAVA_HOME=/usr/java/jdk1.8.0_251-amd64
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib
export PATH=$JAVA_HOME/bin:$PATH
# 更新配置
source /etc/profile
三、zk叢集搭建
1. 解壓zookeeper檔案
tar -zxvf zookeeper檔案
2. 在每一個zk節點上建立zk的資料目錄
mkdir /home/zkdata
3. 在每一個節點存放zk資料的目錄中必須建立一個myid檔案
zk1: echo "1" >> /home/zkdata/myid
zk2: echo "2" >> /home/zkdata/myid
zk3: echo "3" >> /home/zkdata/myid
4. 建立zookeeper的基礎配置檔案zoo.cfg
vi /home/zkdata/zoo.cfg
配置内容如下
# 3001為client端口
# 3002為原子廣播端口
# 3003為選舉投票端口
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/zkdata
clientPort=3001
server.1=zk1:3002:3003
server.2=zk2:3002:3003
server.3=zk3:3002:3003
5. 啟動zk節點,進入zk檔案的bin目錄下執行以下指令
./zkServer.sh start /home/zkdata/zoo.cfg
6. 執行jps指令發現已成功啟動QuorumPeerMain程序
7. 查詢各個zk節點的叢集狀态,發現其中一個節點為leader其餘節點為follower
./zkServer.sh status /home/zkdata/zoo.cfg
8. zk叢集搭建完畢
四、HDFS叢集搭建
1. 在所有hadoop節點添加Cent OS依賴
yum install psmisc -y
2. 安裝hadoop(配置Hadoop環境變量 非必須)
# 添加如下配置
export HADOOP_HOME=/home/hadoop-2.9.2
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
# 更新配置
source /etc/profile
(1) 配置
hadoop-env.sh
修改JAVA相關配置
(2) 配置
core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://ns</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop-2.9.2/data</value>
</property>
<!-- 配置zk叢集節點數 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>zk1:3001,zk2:3001,zk3:3001</value>
</property>
</configuration>
(3) 配置
hdfs-site.xml
<configuration>
<!-- 指定hdfs的nameservices為ns,需要與core-site.xml中保持一緻 -->
<property>
<name>dfs.nameservices</name>
<value>ns</value>
</property>
<!-- ns下面有兩個nameNode分别是nn1,nn2 -->
<property>
<name>dfs.ha.namenodes.ns</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的rpc通信位址 -->
<property>
<name>dfs.namenode.rpc-address.ns.nn1</name>
<value>hadoop1:9000</value>
</property>
<!-- nn1的http通信位址 -->
<property>
<name>dfs.namenode.http-address.ns.nn1</name>
<value>hadoop1:50070</value>
</property>
<!-- nn2的rpc通信位址 -->
<property>
<name>dfs.namenode.rpc-address.ns.nn2</name>
<value>hadoop2:9000</value>
</property>
<!-- nn2的http通信位址 -->
<property>
<name>dfs.namenode.http-address.ns.nn2</name>
<value>hadoop2:50070</value>
</property>
<!-- 指定nameNode的中繼資料在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop1:8485;hadoop2:8485;hadoop3:8485/ns</value>
</property>
<!-- 指定journalNode在本地磁盤中存放資料的位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/zhangjia/journal</value>
</property>
<!-- 開啟nameNode故障時自動切換 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 配置失敗自動切換實作方式 -->
<property>
<name>dfs.client.failover.proxy.provider.ns</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 配置隔離機制。如果ssh預設是22端口,value直接寫sshfence即可 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- 使用隔離機制需要ssh免登陸 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/.ssh/id_rsa</value>
</property>
</configuration>
(4) 配置
slaves
hadoop1
hadoop2
hadoop3
(5) 啟動叢集
(6) 在任意NameNode節點格式化Zk
hdfs zkfc -formatZK
(7) 出現下面這句話則說明格式化成功
ha.ActiveStandbyElector: Successfully created /hadoop-ha/ns in ZK.
(8) 啟動JournalNode節點
因為Journal在HA中需要同步edit log,是以他需要在edit log沒有生成之前啟動
hadoop1: hadoop-daemon.sh start journalnode
hadoop2: hadoop-daemon.sh start journalnode
hadoop3: hadoop-daemon.sh start journalnode
(9) 使用jps發現JournalNode程序已啟動并且在根檔案夾出現journal檔案夾
(10) 格式化NameNode,在選中的active的節點上執行
hdfs namenode -format ns
(11) 啟動hdfs叢集
start-dfs.sh
(12) 在standby 的 NameNode節點上執行如下指令進行同步active節點的edit log
hdfs namenode -bootstrapStandby
(13) 啟動standby節點的NameNode
hadoop-daemon.sh start namenode
此時進入兩個NameNode節點的圖形化界面 http://hadoop1:50070 可以發現一個為active一個為standby
(14) 此時HA叢集搭建完畢