什么是HA?
HA是High Availability的簡寫,即高可用,指當當前工作中的機器宕機后,會自動處理這個異常,並將工作無縫地轉移到其他備用機器上去,以來保證服務的高可用。(簡言之,有兩台機器,一台工作,一台備用,當工作機掛了之后,備用機自動接替。)
HAdoop的HA模式是最常見的生產環境上的安裝部署方式。
Hadoop HA包括NameNode HA 和 ResourceManager HA。
DataNode和NodeManager本身就是被設計為高可用的,不用對它們進行特殊的高可用處理。
下載
百度搜索hadoop進入官網(https://hadoop.apache.org)下載
翻到最下面,選擇release archive
找到對應的版本
選擇tar.gz下載
安裝前基礎配置
修改Hostname
臨時修改hostname
hostname bigdata01
hostname永久生效
vi /etc/sysconfig/network
添加
NETWORKING=yes # 使用網絡
HOSTNAME=bigdata01 # 設置主機名
配置Host
vi /etc/hosts
添加192.168.100.10 bigdata01
關閉防火牆
查看防火牆狀態
systemctl status firewalld
臨時關閉防火牆
systemctl stop firewalld
禁止開機啟動
systemctl disable firewalld
關閉selinux
selinux是Linux一個子安全機制,學習環境可以將它禁用。
vi /etc/sysconfig/selinux
修改SELINUX=disabled
安裝JDK(JAVA)
詳見 linux(CentOS7) 之 jdk1.8 下載及安裝
安裝mysql
詳見 linux(CentOS7) 之 MySQL 5.7.30 下載及安裝
創建用戶
創建hadoop用戶組,密碼為123
useradd hadoop passwd hadoop
123
給root用戶添加寫權限
chmod u+w /etc/sudoers
給hadoop用戶sudo權限(學習環境權限給的大)。
vi /etc/sudoers
root ALL=(ALL) ALL
hadoop ALL=(root) NOPASSWD:ALL
切換hadoop用戶,以下為hadoop用戶執行
su - hadoop
創建基礎目錄
創建存放安裝包的目錄
sudo mkdir /opt/software
創建存放hadoop解壓文件的目錄
sudo mkdir /opt/modules
將/opt/software、/opt/modules文件夾所有者指定為hadoop
sudo chown -R hadoop:hadoop /opt/software sudo chown -R hadoop:hadoop /opt/modules
克隆機器
詳見 linux(CentOS7) 之 克隆虛擬機並配置網絡(固定ip)
三台機器的hosts都配置
sudo vi /etc/hosts
192.168.100.10 bigdata01 192.168.100.11 bigdata02 192.168.100.12 bigdata03
ssh免密登錄配置
注意:
ssh-keygen -t rsa 直接生產出來的格式是OPENSSH,后面HDFS無法實現高可用自動切換。,所以,需要加上 -m PEM
錯誤記錄,詳見 Hadoop 之 高可用不自動切換(ssh密鑰無效 Caused by: com.jcraft.jsch.JSchException: invalid privatekey )
ssh-keygen -t rsa -m PEM
一直按回車,都設置為默認值,然后再當前用戶的Home目錄下的.ssh
目錄中會生成公鑰文件(
id_rsa.pub
)
和私鑰文件(
id_rsa
)
給三台機器分發公鑰
ssh-copy-id bigdata01 ssh-copy-id bigdata02 ssh-copy-id bigdata03
另外兩台機器執行同樣操作,生成公鑰和私鑰后,分發給是三台機器。
配置ntp
詳見 linux(CentOS7) 之 ntp時間同步配置步驟
安裝zookeeper
詳見 linux(CentOS7) 之 zookeeper 下載及安裝
開始安裝
HDFS HA 原理
單NameNode的缺陷存在單點故障的問題,如果NameNode不可用,則會導致整個HDFS文件系統不可用。所以需要設計高可用的HDFS(Hadoop HA)來解決NameNode單點故障的問題。解決的方法是在HDFS集群中設置多個NameNode節點。但是一旦引入多個NameNode,就有一些問題需要解決。
HDFS HA需要保證的四個問題:
1、保證NameNode內存中元數據數據一致,並保證編輯日志文件的安全性; 2、多個NameNode如何協作; 3、客戶端如何能正確地訪問到可用的那個NameNode; 4、怎么保證任意時刻只能有一個NameNode處於對外服務狀態。
解決方法
對於保證NameNode元數據的一致性和編輯日志的安全性,采用Zookeeper來存儲編輯日志文件。
兩個NameNode一個是Active狀態的,一個是Standby狀態的,一個時間點只能有一個Active狀態的。
NameNode提供服務,兩個NameNode上存儲的元數據是實時同步的,當Active的NameNode出現問題時,通過Zookeeper實時切換到Standby的NameNode上,並將Standby改為Active狀態。
客戶端通過連接一個Zookeeper的代理來確定當時哪個NameNode處於服務狀態。
HDFS HA架構圖
HDFS HA架構中有兩台NameNode節點,一台是處於活動狀態(Active)為客戶端提供服務,另外一台處於熱備份狀態(Standby)。
元數據文件有兩個文件:fsimage和edits,備份元數據就是備份這兩個文件。
JournalNode用來實時從Active NameNode上拷貝edits文件,JournalNode有三台也是為了實現高可用。
Standby NameNode不對外提供元數據的訪問,它從Active NameNode上拷貝fsimage文件,從JournalNode上拷貝edits文件,然后負責合並fsimage和edits文件,相當於SecondaryNameNode的作用。最終目的是保證Standby NameNode上的元數據信息和Active NameNode上的元數據信息一致,以實現熱備份。
Zookeeper來保證在Active NameNode失效時及時將Standby NameNode修改為Active狀態。
ZKFC(失效檢測控制)是Hadoop里的一個Zookeeper客戶端,在每一個NameNode節點上都啟動一個ZKFC進程,來監控NameNode的狀態,並把NameNode的狀態信息匯報給Zookeeper集群,其實就是在Zookeeper上創建了一個Znode節點,節點里保存了NameNode狀態信息。當NameNode失效后,ZKFC檢測到報告給Zookeeper,Zookeeper把對應的Znode刪除掉,Standby ZKFC發現沒有Active狀態的NameNode時,就會用shell命令將自己監控的NameNode改為Active狀態,並修改Znode上的數據。
Znode是個臨時的節點,臨時節點特征是客戶端的連接斷了后就會把znode刪除,所以當ZKFC失效時,也會導致切換NameNode。
DataNode會將心跳信息和Block匯報信息同時發給兩台NameNode,DataNode只接受Active NameNode發來的文件讀寫操作指令。
服務器角色規划
bigdata01 |
bigdata02 |
bigdata03 |
NameNode |
NameNode |
|
Zookeeper |
Zookeeper |
Zookeeper |
DataNode |
DataNode |
DataNode |
|
ResourceManage |
ResourceManage |
NodeManager |
NodeManager |
NodeManager |
解壓
解壓hadoop文件到/opt/modules (hadoop-2.7.7.tar.gz 壓縮包存放在此目錄下)
cd /opt/modules tar -zxvf hadoop-2.7.7.tar.gz
配置hadoop環境變量,加在文件末尾。
sudo vi /etc/profile
export HADOOP_HOME="/opt/modules/hadoop-2.7.7"
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
使得配置生效
source /etc/profile
驗證HADOOP_HOME參數值
echo $HADOOP_HOME
/opt/modules/hadoop-2.7.7
分發給其他機器
sudo scp /etc/profile bigdata02: /etc/profile sudo scp /etc/profile bigdata03: /etc/profile
修改配置文件
1、配置 hadoop-env.sh、mapred-env.sh、yarn-env.sh文件的JAVA_HOME參數
2、配置core-site.xml
3、配置hdfs-site.xml
4、配置mapred-site.xml
5、配置yarn-site.xml
配置hadoop-env.sh
cd /opt/modules/hadoop-2.7.7 sudo vi etc/hadoop/hadoop-env.sh
export JAVA_HOME="/opt/modules/jdk1.8.0_281"
配置mapred -env.sh
sudo vi ${HADOOP_HOME}/etc/hadoop/mapred-env.sh
export JAVA_HOME="/opt/modules/jdk1.8.0_281"
配置yarn -env.sh
sudo vi ${HADOOP_HOME}/etc/hadoop/yarn-env.sh
export JAVA_HOME="/opt/modules/jdk1.8.0_281"
配置core-site.xml
vi ${HADOOP_HOME}/etc/hadoop/core-site.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property> <!-- hdfs 地址,ha中是連接到nameservice --> <name>fs.defaultFS</name> <value>hdfs://ns1</value> </property> <property> <!-- Hadoop臨時目錄 --> <name>hadoop.tmp.dir</name> <value>/opt/modules/hadoop-2.7.7/data/tmp</value> </property> <!-- 故障轉移 --> <property> <name>ha.zookeeper.quorum</name> <value>bigdata01:2181,bigdata02:2181,bigdata03:2181</value> </property> </configuration>
namenode格式化默認存放路徑:${HADOOP_HOME}/dfs/name/current/ VERSION
datanode格式化默認存放路徑:${HADOOP_HOME}/dfs/data/current/ VERSION
fs.defaultFS 配置的是HDFS的地址。
hadoop.tmp.dir配置的是Hadoop臨時目錄,比如HDFS的NameNode數據默認都存放這個目錄下,查看*-default.xml等默認配置文件,就可以看到很多依賴${hadoop.tmp.dir}的配置。默認的hadoop.tmp.dir是/tmp/hadoop-${user.name},此時有個問題就是NameNode會將HDFS的元數據存儲在這個/tmp目錄下,如果操作系統重啟了,系統會清空/tmp目錄下的東西,導致NameNode元數據丟失,是個非常嚴重的問題,所以,必須修改這個路徑。
創建臨時目錄
sudo mkdir -p /opt/modules/hadoop-2.7.7/data/tmp
配置hdfs-site.xml
vi ${HADOOP_HOME}/etc/hadoop/hdfs-site.xml
dfs.replication配置的是HDFS存儲時的備份數量,默認3個。
<property> <name>dfs.replication</name> <value>3</value> </property>
文件內容如下:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property> <!-- 為namenode集群定義一個services name --> <name>dfs.nameservices</name> <value>ns1</value> </property> <property> <!-- nameservice 包含哪些namenode,為各個namenode起名 --> <name>dfs.ha.namenodes.ns1</name> <value>nn1,nn2</value> </property> <property> <!-- 名為nn1的namenode 的rpc地址和端口號,rpc用來和datanode通訊 --> <name>dfs.namenode.rpc-address.ns1.nn1</name> <value>bigdata01:8020</value> </property> <property> <!-- 名為nn2的namenode 的rpc地址和端口號,rpc用來和datanode通訊 --> <name>dfs.namenode.rpc-address.ns1.nn2</name> <value>bigdata02:8020</value> </property> <property> <!--名為nn1的namenode 的http地址和端口號,web客戶端 --> <name>dfs.namenode.http-address.ns1.nn1</name> <value>bigdata01:50070</value> </property> <property> <!--名為nn2的namenode 的http地址和端口號,web客戶端 --> <name>dfs.namenode.http-address.ns1.nn2</name> <value>bigdata02:50070</value> </property> <property> <!-- namenode間用於共享編輯日志的journal節點列表 --> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://bigdata01:8485;bigdata02:8485;bigdata03:8485/ns1</value> </property> <property> <!-- journalnode 上用於存放edits日志的目錄 --> <name>dfs.journalnode.edits.dir</name> <value>/opt/modules/hadoop-2.7.7/data/tmp/dfs/jn</value> </property> <property> <!-- 客戶端連接可用狀態的NameNode所用的代理類 --> <name>dfs.client.failover.proxy.provider.ns1</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> <property> <!-- sshfence:防止namenode腦裂,當腦裂時,會自動通過ssh到old-active將其殺掉,將standby切換為active --> <name>dfs.ha.fencing.methods</name> <value>sshfence</value> </property> <property> <!--ssh密鑰文件路徑--> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/home/hadoop/.ssh/id_rsa</value> </property> <!-- 故障轉移 --> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> </configuration>
創建edits日志的存放目錄
sudo mkdir -p /opt/modules/hadoop-2.7.7/data/tmp/dfs/jn
賦權
sudo chown -R hadoop:hadoop /opt/modules/hadoop-2.7.7
配置slaves文件(指定HDFS上有哪些DataNode節點)
sudo vi ${HADOOP_HOME}/etc/hadoop/slaves
bigdata01
bigdata02
bigdata03
配置mapred-site.xml
默認是沒有mapred-site.xml文件,但是有個mapred-site.xml.template配置模板文件。復制模板生成mapred-site.xml。
cp etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml
vi etc/hadoop/mapred-site.xml
<configuration> <property> <!--指定mapreduce運行在yarn框架上--> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <!--設置mapreduce的歷史服務器安裝在BigData01機器上--> <name>mapreduce.jobhistory.address</name> <value>bigdata01:10020</value> </property> <property> <!--設置歷史服務器的web頁面地址和端口號--> <name>mapreduce.jobhistory.webapp.address</name> <value>bigdata01:19888</value> </property> </configuration>
配置yarn-site.xml
YARN HA原理
ResouceManager記錄着當前集群的資源分配情況和JOB運行狀態,YRAN HA 利用Zookeeper等共享存儲介質來存儲這些信息來達到高可用。利用Zookeeper來實現ResourceManager自動故障轉移。
YARN HA架構圖
MasterHADaemon:控制RM的 Master的啟動和停止,和RM運行在一個進程中,可以接收外部RPC命令。
共享存儲:Active Master將信息寫入共享存儲,Standby Master讀取共享存儲信息以保持和Active Master同步。
ZKFailoverController:基於Zookeeper實現的切換控制器,由ActiveStandbyElector和HealthMonitor組成,ActiveStandbyElector負責與Zookeeper交互,判斷所管理的Master是進入Active還是Standby;HealthMonitor負責監控Master的活動健康情況,是個監視器。
Zookeeper:核心功能是維護一把全局鎖控制整個集群上只有一個Active的ResourceManager。
vi etc/hadoop/yarn-site.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property> <!-- 配置yarn的默認混洗方式,選擇為mapreduce的默認混洗算法 --> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <!-- 是否啟用日志聚集功能 --> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <property> <!-- 是配置聚集的日志在HDFS上最多保存多長時間 --> <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>rm12,rm13</value> </property> <property> <!-- 指定第一個節點的所在機器 --> <name>yarn.resourcemanager.hostname.rm12</name> <value>bigdata02</value> </property> <property> <!-- 指定第二個節點所在機器 --> <name>yarn.resourcemanager.hostname.rm13</name> <value>bigdata03</value> </property> <property> <!-- 指定resourcemanger ha 所用的zookeeper 節點 --> <name>yarn.resourcemanager.zk-address</name> <value>bigdata01:2181,bigdata02:2181,bigdata03:2181</value> </property> <property> <!-- 開啟Recovery后,ResourceManger會將應用的狀態等信息保存到yarn.resourcemanager.store.class配置的存儲介質中,重啟后會load這些信息,並且NodeManger會將還在運行的container信息同步到ResourceManager,整個過程不影響作業的正常運行。 --> <name>yarn.resourcemanager.recovery.enabled</name> <value>true</value> </property> <property> <!-- 指定yarn.resourcemanager.store.class的存儲介質(HA集群只支持ZKRMStateStore) --> <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> </property> </configuration>
分發到其他節點
分發之前先將share/doc目錄刪除,這個目錄中是幫助文件,並且很大,可以刪除。
rm -rf /opt/modules/hadoop-2.7.7/share/doc
scp -r /opt/modules/hadoop-2.7.7 bigdata02:/opt/modules scp -r /opt/modules/hadoop-2.7.7 bigdata03:/opt/modules
格式化NameNode
格式化是對HDFS這個分布式文件系統中的DataNode進行分塊,統計所有分塊后的初始元數據的存儲在NameNode中。
格式化后,查看core-site.xml里hadoop.tmp.dir(/opt/modules/hadoop-2.7.7/data/tmp/目錄)指定的目錄下是否有了dfs目錄,如果有,說明格式化成功。
因為按照前面的規划01,02兩台機器分配NameNode,需格式化。
三台機器啟動 journalnode
hadoop-daemon.sh start journalnode
三台機器啟動zookeeper
bigdata01上操作:
cd /opt/modules/zookeeper-3.5.6
bin/zkServer.sh start
bigdata02上操作:
cd /opt/modules/zookeeper-3.5.6
bin/zkServer.sh start
bigdata03上操作:
cd /opt/modules/zookeeper-3.5.6
bin/zkServer.sh start
在bigdata01進行NameNode格式化
cd /opt/modules/hadoop-2.7.7 bin/hdfs namenode -format
在bigdata02進行NameNode格式化
cd /opt/modules/hadoop-2.7.7 bin/hdfs namenode -bootstrapStandby
格式化時,這里注意hadoop.tmp.dir目錄的權限問題,應該hadoop普通用戶有讀寫權限才行 (前面創建目錄時已經給了權限)。
sudo chown -R hadoop:hadoop /opt/modules/hadoop-2.7.7
查看NameNode格式化后的目錄
ll /opt/modules/hadoop-2.7.7/data/tmp/dfs/name/current/
fsimage是NameNode元數據在內存滿了后,持久化保存到的文件。
fsimage*.md5 是校驗文件,用於校驗fsimage的完整性。
seen_txid 是hadoop的版本
vession文件里保存
namespaceID:NameNode的唯一ID
clusterID:集群ID NameNode和DataNode的集群ID應該一致,表明是一個集群。
注意:
如果需要重新格式化NameNode,需要先將原來NameNode和DataNode下的文件全部刪除,不然會報錯,NameNode和DataNode所在目錄是在core-site.xml中hadoop.tmp.dir、dfs.namenode.name.dir、dfs.datanode.data.dir屬性配置的。
因為每次格式化,默認是創建一個集群ID,並寫入NameNode和DataNode的VERSION文件中(VERSION文件所在目錄為dfs/name/current 和 dfs/data/current),重新格式化時,默認會生成一個新的集群ID,如果不刪除原來的目錄,會導致namenode中的VERSION文件中是新的集群ID,而DataNode中是舊的集群ID,不一致時會報錯。
格式化zookeeper
hdfs zkfc -formatZK
啟動集群
啟動集群NameNode、DataNode、JournalNode、zkfc(zkfc只針對NameNode監聽)
${HADOOP_HOME}/sbin/start-dfs.sh
在bigdata-senior01上啟動yarn:
sbin/start-yarn.sh
在bigdata02、bigdata03上啟動resourcemanager:
bigdata02上執行:
sbin/yarn-daemon.sh start resourcemanager
bigdata03上執行:
sbin/yarn-daemon.sh start resourcemanage
開啟歷史服務
Hadoop開啟歷史服務可以在web頁面上查看Yarn上執行job情況的詳細信息。可以通過歷史服務器查看已經運行完的Mapreduce作業記錄,比如用了多少個Map、用了多少個Reduce、作業提交時間、作業啟動時間、作業完成時間等信息。
開啟歷史服務
sbin/mr-jobhistory-daemon.sh start historyserver
web頁面查看地址http://bigdata01:19888/
歷史服務器的Web端口默認是19888,可以查看Web界面。
但是在上面所顯示的某一個Job任務頁面的最下面,Map和Reduce個數的鏈接上,點擊進入Map的詳細信息頁面,再查看某一個Map或者Reduce的詳細日志是看不到的,是因為沒有開啟日志聚集服務。
查看進程
jps
bigdata01:
bigdata02:
bigdata03:
測試HDFS HA
注意:
如果使用hostname訪問 ,需要配置宿主機的hostname:
給C:\Windows\System32\drivers\etc下的hosts文件,添加下面兩行
bigdata01 192.168.100.11
bigdata02 192.168.100.12
查看HDFS Web頁面
此時bigdata01的狀態是active,bigdata02的狀態是standby。
殺掉bigdata01的namenode進程,然后查看bigdata01無法訪問,bigdata02狀態變為active。
Web客戶端訪問bigdata02機器上的resourcemanager正常,它是active狀態的。
http://bigdata02:8088/cluster
訪問另外一個resourcemanager,因為他是standby,會自動跳轉到active的resourcemanager。
另,可以手動切換active狀態:
切換第一台為active狀態:
bin/hdfs haadmin -transitionToActive nn1
添加forcemanual參數,可以強制指定某個NameNode為Active狀態。
bin/hdfs haadmin -transitionToActive -forcemanual nn1
測試YARN HA
運行一個mapreduce job
bin/yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jar wordcount /wc.input /input
在job運行過程中,將Active狀態的resourcemanager進程殺掉。觀察另外一個resourcemanager是否可以自動接替。
bigdata02的resourcemanage Web客戶端已經不能訪問,bigdata03的resourcemanage已經自動變為active狀態。觀察mapreduce job 能順利完成,沒有因為resourcemanager的意外故障而影響運行。
附:
查看HDFS Web頁面http://bigdata01:50070
YARN的Web頁面地址 http://bigdata02:8088
YARN的Web頁面歷史服務器地址:http://bigdata01:19888
OK,安裝完成!
優化中......