hadoop高可用安裝和原理詳解
本篇主要從hdfs的namenode和resourcemanager的高可用進行安裝和原理的闡述。
一、HA安裝
1、基本環境準備
1.1.1、centos7虛擬機器安裝,詳情見VMware安裝Centos7虛擬機器
1.1.2、關閉防火牆
systemctl stop firewalld.service systemctl disable firewalld.service
1.1.3、修改selinux
vim /etc/selinux/config
將SELINUX=enforcing改為SELINUX=disabled
[hadoop@lgh2 ~]$ cat /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled # SELINUXTYPE= can take one of three two values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted
1.1.4、安裝java
java 安裝 tar -zxvf jdk-8u201-linux-x64.tar.gz -C /usr/local/ vim /etc/profile export JAVA_HOME=/usr/local/jdk1.8.0_201 export JRE_HOME=/usr/local/jdk1.8.0_201/jre export CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
source /etc/profile
1.1.5、新增使用者hadoop
groupadd hadoop useradd -g hadoop -d /home/hadoop echo 'hadoop' | passwd hadoop --stdin
1.1.6、修改/etc/hosts
cat /etc/hosts 192.168.88.131 lgh1 192.168.88.132 lgh2 192.168.88.133 lgh3
如上環境我們準備三臺機器,如上1.1.6所見:
1.1.7、配置免密登入
ssh-keygen -t rsa #這個操作需要連續三次按enter鍵, ssh-copy-id lgh3 ssh-copy-id lgh2 ssh-copy-id lgh1
1.1.8、配置時間同步(這個很重要,在生產環境必定要有,不過自己玩也可以不用配置)
首先我們選定192.168.88.131(lgh1)這臺為時間標準的節點,其他兩臺機器同這個節點進行同步
設定192.168.88.131這個節點:
yum install -y ntp #如果沒有安裝就安裝 [root@lgh1 ~]# rpm -qa | grep ntp #檢視安裝結果 ntp-4.2.6p5-29.el7.centos.x86_64 #用來提供時間同步服務 ntpdate-4.2.6p5-29.el7.centos.x86_64 #和某臺伺服器進行同步
修改/etc/ntp.conf檔案
egrep -v "^$|#" /etc/ntp.conf [root@lgh1 ~]# egrep -v "^$|#" /etc/ntp.conf driftfile /var/lib/ntp/drift restrict default nomodify notrap nopeer noquery restrict 192.168.88.0 mask 255.255.255.0 nomodify notrap restrict 127.0.0.1 restrict ::1 #server 0.centos.pool.ntp.org iburst #server 1.centos.pool.ntp.org iburst #server 2.centos.pool.ntp.org iburst #server 3.centos.pool.ntp.org iburst server 127.127.1.0 fudge 127.127.1.0 stratum 10 includefile /etc/ntp/crypto/pw keys /etc/ntp/keys disable monitor
systemctl enable ntpd #啟動
其他兩個節點:lhg2和lgh3設定如下:
首先要安裝ntpd:yum install -y ntp #如果沒有安裝則要安裝
新增crontab -e
*/5 * * * * /usr/sbin/ntpdate -u 192.168.88.131 #表示每五分鐘和131時間同步一次
測試:(可以通過如下命令修改131的時間,看其他兩個節點是否能同步成功,親測成功)
date "+%Y-%m-%d %H:%M:%S"
date -s '2018-09-20 10:02:02'
2、hadoop高可用安裝
1.2.1、安裝規劃--目錄
mkdir -p /opt/hadoop #存放hadoop檔案,安裝目錄 chown -R hadoop:hadoop /opt/hadoop mkdir -p /opt/data/hadoop/hdfs #存放namenode和datanode的資料 mkdir -p /opt/data/hadoop/tmp #存放臨時檔案 chown -R hadoop:hadoop /opt/data/hadoop/hdfs chown -R hadoop:hadoop /opt/data/hadoop/tmp
1.2.2、角色規劃
解壓1.2.3、zookeeper安裝
cd /opt/hadoop tar -zxvf zookeeper-3.4.8.tar.gz ln -s zookeeper-3.4.8 zookeeper
配置環境變數
vim /etc/profile export ZOOKEEPER_HOME=/opt/hadoop/zookeeper export PATH=$ZOOKEEPER_HOME/bin:$ZOOKEEPER_HOME/conf:$PATH source /etc/profile
修改配置zoo.cfg
cd /opt/hadoop/zookeeper/conf cp zoo_sample.cfg zoo.cfg vim zoo.cfg tickTime=2000 #伺服器與客戶端之間互動的基本時間單元(ms) initLimit=10 # 此配置表示允許follower連線並同步到leader的初始化時間,它以tickTime的倍數來表示。當超過設定倍數的tickTime時間,則連線失敗 syncLimit=5 # Leader伺服器與follower伺服器之間資訊同步允許的最大時間間隔,如果超過次間隔,預設follower伺服器與leader伺服器之間斷開連結 dataDir=/opt/hadoop/zookeeper/data #儲存zookeeper資料路徑 dataLogDir=/opt/hadoop/zookeeper/dataLog #儲存zookeeper日誌路徑,當此配置不存在時預設路徑與dataDir一致 clientPort=2181 #客戶端訪問zookeeper時經過伺服器端時的埠號 server.1=lgh1:2888:3888 #表示了不同的zookeeper伺服器的自身標識,作為叢集的一部分,每一臺伺服器應該知道其他伺服器的資訊 server.2=lgh2:2888:3888 server.3=lgh3:2888:3888 maxClientCnxns=60 #限制連線到zookeeper伺服器客戶端的數量
修改myid檔案
cd /opt/hadoop/zookeeper mkdir data dataLog cd /opt/hadoop/zookeeper/data touch myid && echo 1 > myid
分發並修改myid檔案
scp -r /opt/hadoop/zookeeper hadoop@lgh2:/opt/hadoop/ scp -r /opt/hadoop/zookeeper hadoop@lgh3:/opt/hadoop/
vim /opt/hadoop/zookeeper/data/myid #lgh2 修改為2 vim /opt/hadoop/zookeeper/data/myid #lgh3 修改為3
啟動並檢視狀態
zkServer.sh start zkServer.sh status
一臺為leader狀態,其他兩個為follower狀態
1.2.4、解壓hadoop
cd /opt/hadoop tar -zxvf hadoop-2.7.7.tar.gz ln -s hadoop-2.7.7 hadoop
1.2.5、配置環境變數
export HADOOP_HOME="/opt/hadoop/hadoop-2.7.7" export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
1.2.6、修改hadoop-env.sh、mapred-env.sh、yarn-env.sh
export JAVA_HOME=/usr/local/jdk1.8.0_201
1.2.7、修改hdfs-site.xml檔案
<configuration> <property> <!-- 為namenode叢集定義一個services name --> <name>dfs.nameservices</name> <value>mycluster</value> </property> <property> <!-- nameservice 包含哪些namenode,為各個namenode起名 --> <name>dfs.ha.namenodes.mycluster</name> <value>nn1,nn2</value> </property> <property> <!-- 名為nn1的namenode 的rpc地址和埠號,rpc用來和datanode通訊 --> <name>dfs.namenode.rpc-address.mycluster.nn1</name> <value>lgh1:8020</value> </property> <property> <!-- 名為nn2的namenode 的rpc地址和埠號,rpc用來和datanode通訊 --> <name>dfs.namenode.rpc-address.mycluster.nn2</name> <value>lgh2:8020</value> </property> <property> <!--名為nn1的namenode 的http地址和埠號,web客戶端 --> <name>dfs.namenode.http-address.mycluster.nn1</name> <value>lgh1:50070</value> </property> <property> <!--名為nn2的namenode 的http地址和埠號,web客戶端 --> <name>dfs.namenode.http-address.mycluster.nn2</name> <value>lgh2:50070</value> </property> <property> <!-- namenode間用於共享編輯日誌的journal節點列表 --> <!-- 指定NameNode的edits元資料的共享儲存位置。也就是JournalNode列表 該url的配置格式:qjournal://host1:port1;host2:port2;host3:port3/journalId journalId推薦使用nameservice,預設埠號是:8485 --> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://lgh1:8485;lgh2:8485;lgh3:8485/mycluster</value> </property> <property> <!-- journalnode 上用於存放edits日誌的目錄 --> <name>dfs.journalnode.edits.dir</name> <value>/opt/hadoop/hadoop/tmp/data/dfs/jn</value> </property> <property> <!-- 客戶端連線可用狀態的NameNode所用的代理類 --> <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 shell(/bin/true) </value> </property> <!-- 使用sshfence隔離機制時需要ssh免登陸 --> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/home/hadoop/.ssh/id_rsa</value> </property> <!-- journalnode叢集之間通訊的超時時間 --> <property> <name>dfs.qjournal.start-segment.timeout.ms</name> <value>60000</value> </property> <!-- 指定副本數 --> <property> <name>dfs.replication</name> <value>2</value> </property> <!--namenode路徑--> <property> <name>dfs.namenode.name.dir</name> <value>/opt/data/hadoop/hdfs/nn</value> </property> <!--datanode路徑--> <property> <name>dfs.datanode.data.dir</name> <value>/opt/data/hadoop/hdfs/dn</value> </property> <!-- 開啟NameNode失敗自動切換 --> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> <!-- 啟用webhdfs --> <property> <name>dfs.webhdfs.enabled</name> <value>true</value> </property> <!-- 配置sshfence隔離機制超時時間 --> <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>30000</value> </property> <property> <name>ha.failover-controller.cli-check.rpc-timeout.ms</name> <value>60000</value> </property> </configuration>
1.2.8、修改core-site.xml
<configuration> <property> <!-- hdfs 地址,ha中是連線到nameservice --> <name>fs.defaultFS</name> <value>hdfs://mycluster</value> </property> <property> <!-- --> <name>hadoop.tmp.dir</name> <value>/opt/data/hadoop/tmp</value> </property> <!-- 指定zookeeper地址 --> <property> <name>ha.zookeeper.quorum</name> <value>lgh1:2181,lgh2:2181,lgh3:2181</value> </property> <!-- hadoop連結zookeeper的超時時長設定 --> <property> <name>ha.zookeeper.session-timeout.ms</name> <value>30000</value> <description>ms</description> </property> <property> <name>fs.trash.interval</name> <value>1440</value> </property> <property> <name>hadoop.proxyuser.hdfs.groups</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.hdfs.hosts</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.hive.groups</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.hive.hosts</name> <value>*</value> </property> </configuration>
1.2.9、修改yarn-site.xml
<configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <property> <name>yarn.log-aggregation.retain-seconds</name> <value>106800</value> </property> <property> <!-- 啟用resourcemanager的ha功能 --> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <property> <!-- 為resourcemanage ha 叢集起個id --> <name>yarn.resourcemanager.cluster-id</name> <value>yarn-cluster</value> </property> <property> <!-- 指定resourcemanger ha 有哪些節點名 --> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property> <property> <!-- 指定第一個節點的所在機器 --> <name>yarn.resourcemanager.hostname.rm1</name> <value>lgh2</value> </property> <property> <!-- 指定第二個節點所在機器 --> <name>yarn.resourcemanager.hostname.rm2</name> <value>lgh3</value> </property> <property> <!-- 指定resourcemanger ha 所用的zookeeper 節點 --> <name>yarn.resourcemanager.zk-address</name> <value>lgh1:2181,lgh2:2181,lgh3: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> <property> <name>yarn.log.server.url</name> <value>http://lgh2:19888/jobhistory/logs/</value> </property> </configuration>
1.2.10、修改 slaves
lgh1 lgh2 lgh3
1.2.11、分發到其他兩個節點
scp /opt/hadoop/hadoop-2.7.7 hadoop@lgh2:/opt/hadoop/ scp /opt/hadoop/hadoop-2.7.7 hadoop@lgh3:/opt/hadoop/
1.2.12、格式化nomenode和zookeeper
[hadoop@lgh1 ~]$ hdfs namenode -format [hadoop@lgh2 ~]$ hdfs namenode -bootstrapStandby
[hadoop@lgh1 ~]$ hdfs zkfc -formatZK #格式化zookeeper
1.2.13、啟動
stop-dfs.sh #關閉所有journalnode start-dfs.sh #啟動namenode,datanode,journalnode等元件 start-yarn.sh #啟動yarn [hadoop@lgh2 ~]$ /opt/hadoop/hadoop/sbin/yarn-daemon.sh start resourcemanager #這裡一定要注意是yarn-daemon.sh,啟動resourcemanager [hadoop@lgh3 ~]$ /opt/hadoop/hadoop/sbin/yarn-daemon.sh start resourcemanager
1.2.14、檢視程序
jps (圖片不協調。。。)
1.2.15、 訪問頁面(namenode)
192.168.88.131:50070
192.168.88.132:50070
1.2.16、測試namenode故障轉移
在節點192.168.88.132上執行:
[hadoop@lgh2 ~]$ /opt/hadoop/hadoop/sbin/hadoop-daemon.sh stop namenode
然後我們恢復192.168.88.132的namenode
[hadoop@lgh2 ~]$ /opt/hadoop/hadoop/sbin/hadoop-daemon.sh start namenode
該節點變成了standby節點。說明故障轉移成功
1.2.17、檢視yarn頁面訪問
resourcemanager的故障測試:
[hadoop@lgh3 ~]$ /opt/hadoop/hadoop/sbin/yarn-daemon.sh stop resourcemanager #停掉lgh3節點上的resourcemanager
這裡不截圖了,很成功
到這裡hadoop的高可用就安裝完畢了(不過筆者這個中踩了不少坑,遇到一些奇葩問題,但是沒有記錄,總之,刪除掉生成的東西,多格式化幾次試試)
刪除的目錄有:
rm -rf /opt/data/hadoop/hdfs/*
rm -rf /opt/data/hadoop/tmp/*
rm -rf /opt/hadoop/hadoop/logs/*
二、基本原理
1、namenode高可用
我們知道namenode是整個hdfs的核心,如果namenode掛了,那麼整個hdfs檔案系統也不能提供服務,所以hadoop對hdfs提供了高可用的方案,即Hadoop HA,hdfs的高可用提供了兩種方案,一種是基於QJM(Quorum Journal Manager)的,一種是基於NFS的,我們用的一般都是基於QJM的,所以這裡也是講基於QJM的高可用,高可用用來解決NameNode單點故障的問題。解決的方法是在HDFS叢集中設定多個NameNode節點。那麼提供多個namenode必定存在新的問題:
1、如何保證NameNode記憶體中元資料資料一致,並保證編輯日誌檔案的安全性。
2、多個NameNode如何協作
3、客戶端如何能正確地訪問到可用的那個NameNode。
4、怎麼保證任意時刻只能有一個NameNode處於對外服務狀態
針對如上問題,hadoop提供瞭如下解決方案:
對於保證NameNode元資料的一致性和編輯日誌的安全性,採用Zookeeper來儲存編輯日誌檔案。
兩個NameNode一個是Active狀態的,一個是Standby狀態的,一個時間點只能有一個Active狀態的 。
NameNode提供服務,兩個NameNode上儲存的元資料是實時同步的,當Active的NameNode出現問題時,通過Zookeeper實時切換到Standby的NameNode上,並將Standby改為Active狀態。
客戶端通過連線一個Zookeeper的代理來確定當時哪個NameNode處於服務狀態。
我們看一下hdfs高可用的架構圖:如下圖所示:
HDFS HA架構中有兩臺NameNode節點,一臺是處於活動狀態(Active)為客戶端提供服務,另外一臺處於熱備份狀態(Standby)。
DataNode會將心跳資訊和Block彙報資訊同時發給兩臺NameNode,DataNode只接受Active NameNode發來的檔案讀寫操作指令。為了使備用節點保持其狀態與Active節點同步,兩個節點都與一組稱為“JournalNodes”(JN)的單獨守護程序通訊。當Active節點執行任何名稱空間修改時,它會將修改記錄持久地記錄到大多數這些JN中。待機節點能夠從JN讀取編輯,並且不斷觀察它們對編輯日誌的更改。當備用節點看到編輯時,它會將它們應用到自己的名稱空間。如果發生故障轉移,Standby將確保在將自身升級為Active狀態之前已從JournalNodes讀取所有編輯內容。這可確保在發生故障轉移之前完全同步名稱空間狀態。注意:必須至少有3個JournalNode守護程序,因為編輯日誌修改必須寫入大多數JN。這將允許系統容忍單個機器的故障。您也可以執行3個以上的JournalNodes,但為了實際增加系統可以容忍的失敗次數,您應該執行奇數個JN(即3,5,7等)。請注意:當使用N JournalNodes執行時,系統最多可以容忍(N-1)/ 2個故障並繼續正常執行。
Zookeeper來保證在Active NameNode失效時及時將Standby NameNode修改為Active狀態。
故障檢測 - 叢集中的每個NameNode計算機都在ZooKeeper中維護一個持久會話。如果計算機崩潰,ZooKeeper會話將過期,通知其他NameNode應該觸發故障轉移。Active NameNode選舉 - ZooKeeper提供了一種簡單的機制,可以將節點專門選為活動節點。如果當前活動的NameNode崩潰,則另一個節點可能在ZooKeeper中採用特殊的獨佔鎖,指示它應該成為下一個活動的。
ZKFailoverController(ZKFC)是一個新元件,它是一個ZooKeeper客戶端,它還監視和管理NameNode的狀態。執行NameNode的每臺機器也執行ZKFC,ZKFC負責:
1、執行狀況監視 : ZKFC定期使用執行狀況檢查命令對其本地NameNode進行ping操作。只要NameNode及時響應健康狀態,ZKFC就認為該節點是健康的。如果節點已崩潰,凍結或以其他方式進入不健康狀態,則執行狀況監視器會將其標記為執行狀況不佳。
2、ZooKeeper會話管理 :當本地NameNode執行正常時,ZKFC在ZooKeeper中保持會話開啟。如果本地NameNode處於活動狀態,它還擁有一個特殊的“鎖定”znode。此鎖使用ZooKeeper對“短暫”節點的支援; 如果會話過期,將自動刪除鎖定節點
3、基於ZooKeeper的選舉 :如果本地NameNode是健康的,並且ZKFC發現沒有其他節點當前持有鎖znode,它將自己嘗試獲取鎖。如果成功,那麼它“贏得了選舉”,並負責執行故障轉移以使其本地NameNode處於活動狀態。故障轉移過程類似於上述手動故障轉移:首先,必要時對先前的活動進行隔離,然後本地NameNode轉換為活動狀態。
元資料檔案有兩個檔案:fsimage和edits,備份元資料就是備份這兩個檔案。JournalNode用來實時從Active NameNode上拷貝edits檔案,JournalNode有三臺也是為了實現高可用。
Standby NameNode不對外提供元資料的訪問,它從Active NameNode上拷貝fsimage檔案,從JournalNode上拷貝edits檔案,然後負責合併fsimage和edits檔案,相當於SecondaryNameNode的作用。最終目的是保證Standby NameNode上的元資料資訊和Active NameNode上的元資料資訊一致,以實現熱備份。
2、resourcemanager高可用
首先我們來看一下官方提供的架構圖:如圖所示:
ResourceManager HA通過主動/備用架構實現 - 在任何時間點,其中一個RM處於活動狀態,並且一個或多個RM處於待機模式,等待活動RM出現故障或者宕機時機。轉換為活動的觸發器來自管理員(通過CLI)或啟用自動故障轉移時的整合故障轉移控制器。
RM可以選擇嵌入基於Zookeeper的ActiveStandbyElector來決定哪個RM應該是Active。當Active關閉或無響應時,另一個RM自動被選為Active,然後接管。請注意,不需要像HDFS那樣執行單獨的ZKFC守護程式,因為嵌入在RM中的ActiveStandbyElector充當故障檢測器和領導者選擇器而不是單獨的ZKFC守護程式。
當存在多個RM時,客戶端和節點使用的配置(yarn-site.xml)應該列出所有RM。客戶端,應用程式管理器ApplicationMaster(AM)和節點管理器NodeManager(NM)嘗試以迴圈方式連線到RM,直到它們到達活動RM。如果活動停止,他們將恢復迴圈輪詢,直到他們連線到新的RM
更多相關文章:hadoop生態系列
參考:
https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html
https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html
https://www.cnblogs.com/zsql/p/10736420.html
https://blog.csdn.net/hliq5399/article/details/7819