centos7 搭建ha(高可用)hadoop2.7.3叢集
寫在前面
作為一個單體應用開發人員對於理解分散式應用和微服務的理論還可以。但是部署分散式環境來說還是一個挑戰。最近在學習hadoop,正也把學習的東西分享出來,希望幫助感興趣的人。
前面一章寫了centos7搭建hadoop叢集
再跟著做本章實驗前建議初學者先去實驗上一章的內容。有任何問題歡迎反饋,我也好做出修改。
ha(高可用)hadoop2.7.3叢集,主要是為了消除spof(單點故障),解決方案有很多,但是思想相同。(如:Linux HA, VMware FT, shared NAS+NFS, BookKeeper, QJM/Quorum Journal Manager, BackupNode等),大家可以搜尋響應的方案。下面我主要實現的QJM/Quorum Journal Manager方案
先期準備
主機 | 系統 | ip地址 | 軟體 | 程序 |
---|---|---|---|---|
node1 | centos7 | 192.168.206.129 | jdk8+,hadoop | NameNode、DFSZKFailoverController(zkfc)、ResourceManager |
node2 | centos7 | 192.168.206.130 | jdk8+,hadoop | NameNode、DFSZKFailoverController(zkfc)、ResourceManager |
node3 | centos7 | 192.168.206.131 | jdk8+,hadoop,zookeeper | DataNode、NodeManager、JournalNode、QuorumPeerMain |
node4 | centos7 | 192.168.206.132 | jdk8+,hadoop,zookeeper | DataNode、NodeManager、JournalNode、QuorumPeerMain |
node5 | centos7 | 192.168.206.133 | jdk8+,hadoop,zookeeper | DataNode、NodeManager、JournalNode、QuorumPeerMain |
參照上面的列表建立5臺虛擬機器(吐槽一下你的記憶體不夠可不行,至少每個虛擬機器1G記憶體),建立hadoop使用者,修改每個虛擬機器的靜態IP、主機名、主機名與IP的對映,關閉防火牆和selinux不熟悉的參照我的
剩下的就是安裝,環境變數設定,啟動了,請有些耐心。
我的理解
hadoop的設計是主從分散式原理,主(namenod 簡稱nn)只有一個不負責記錄實際資料,只記錄元資料(檔案描述資訊),從(datanode 簡稱 dn)有多個用來記錄實際資料。從(dn)寫入資料並備份(預設3)成功後把塊資訊彙報個主(nn)並維持一個心跳。
所以從我的理解角度來看,資料不會出現spof。而影響整個叢集是否能正常工作的地方就是主(nn),如果nn故障整個叢集就癱瘓了也就是所謂的spof.
如何避免nn的spof,我的理解就是備份nn,並在其中一個nn故障時快速切換到可用的nn
要解決的問題:熱備份,快速啟動,防止腦裂,我所說的大家不瞭解的話可以網上查查。我簡單說下
1. 熱備份:就是要保證備份資料必須實時,不能丟失,和元資料一樣
2. 快速啟動:客戶端感覺不出來,(因為nn啟動時很慢的,根據記錄的元資料多少有關)
3. 防止腦裂:hadoop叢集任何時刻必須保證只有一個領導者(主nn),也就是一山不能容二虎,除非一公一母。母也就是備份 standby namenode ( snn )
QJM/Quorum Journal Manager方案:
action:表示在服務的
standby:表示不再服務,熱備份中的
JN:JournalNode 儲存服務中nn的狀態,用來共享
zkfc:DFSZKFailoverController 健康監測 ,會話管理 ,master選舉,防止腦裂
上面的東西看不明白的咱們可以討論的
開始安裝
jdk8安裝
zookeeper安裝在node3,node4,node5上
下載zookeeper-3.4.9.tar
如果你和我一樣就解壓在hadoop主題目錄下
tar -xzvf zookeeper-3.4.9.tar.gz
hadoop安裝在所有node上
不會安裝jdk和hadoop的請看上一章
配置環境變數
# Java Environment Variables
export JAVA_HOME=/usr/java/jdk1.8.0_121
export PATH=$PATH:$JAVA_HOME/bin
# Hadoop Environment Variables
export HADOOP_HOME=/home/hadoop/hadoop-2.7.3
export HADOOP_INSTALL=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export HADOOP_OPTS="-Djava.library.path=${HADOOP_HOME}/lib/native"
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin
# Zookeeper Environment Variables
export ZOOKEEPER_HOME=/home/hadoop/zookeeper-3.4.9
export PATH=$PATH:$ZOOKEEPER_HOME/bin
zookeeper配置,node3,node4,node5
存放在zookeeper安裝目錄的conf目錄下起名zoo.cfg
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
#dataDir=/tmp/zookeeper 在你的主機中建立相應的目錄
dataDir=/home/hadoop/zookeeper-3.4.9/data
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.1=node3:2888:3888
server.2=node4:2888:3888
server.3=node5:2888:3888
在node3,node4,node5的/home/hadoop/zookeeper-3.4.9/data
下建立一個myid的檔案裡面寫一個數字 要和上面配置中的資訊一直如
server.1=node3:2888:3888 表示要在node3的myid檔案中寫一個1的數字
server.2=node4:2888:3888表示要在node4的myid檔案中寫一個2的數字
server.3=node5:2888:3888表示要在node5的myid檔案中寫一個3的數字
hadoop ha配置,在每個node上
core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://cluster</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/hadoop-2.7.3/tmp</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>node3:2181,node4:2181,node5:2181</value>
</property>
</configuration>
hdfs-site.xml
<configuration>
<property>
<name>dfs.nameservices</name>
<value>cluster</value>
</property>
<property>
<name>dfs.ha.namenodes.cluster</name>
<value>node1,node2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.cluster.node1</name>
<value>node1:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.cluster.node1</name>
<value>node1:50070</value>
</property>
<property>
<name>dfs.namenode.rpc-address.cluster.node2</name>
<value>node2:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.cluster.node2</name>
<value>node2:50070</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node3:8485;node4:8485;node5:8485/cluster</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/hadoop/hadoop-2.7.3/journaldata</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.client.failover.proxy.provider.cluster</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>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
</configuration>
mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
yarn-site.xml
<configuration>
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>yrc</value>
</property>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>node1</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>node2</value>
</property>
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>node3:2181,node4:2181,node5:2181</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
slaves
node3
node4
node5
啟動步驟
- 先啟動zookeeper服務,分別在node3,node4,node5上執行
zkServer.sh start
- 啟動journalnode,分別在node3,node4,node5上執行
hadoop-daemon.sh start journalnode
注意只有第一次需要這麼啟動,之後啟動hdfs會包含journalnode - 格式化HDFS,在node1上執行
hdfs namenode -format
注意:格式化之後需要把tmp目錄拷給node2(不然node2的namenode起不來) - 格式化ZKFC,在node1上執行
hdfs zkfc -formatZK
- 啟動HDFS,在node1上執行,
start-dfs.sh
- 啟動YARN,在node1上執行,
start-yarn.sh
- node2的resourcemanager需要手動單獨啟動:
yarn-daemon.sh start resourcemanager
在每個節點上執行jps
如果看到內容和我上面表中的程序對應,成功,不對應以失敗。歡迎討論!!!