在上一篇博客的基础上做这次实验

系统环境:RHEL6.5 selinux and iptables is disabled
Hadoop 、jdk、zookeeper 程序使用 nfs 共享同步配置文件
软件版本:hadoop-2.7.3.tar.gz zookeeper-3.4.9.tar.gz jdk-7u79-linux-x64.tar.gz    hbase-1.2.4-bin.tar.gz

server1作为master,server5作为备用master,server2、server3和server4作为集群服务器

在典型的 HA 集群中,通常有两台不同的机器充当 NN。在任何时间,只有一台机器处于Active 状态;另一台机器是处于 Standby 状态。Active NN 负责集群中所有客户端的操作;而 Standby NN 主要用于备用,它主要维持足够的状态,如果必要,可以提供快速的故障恢复。
为了让 Standby NN 的状态和 Active NN 保持同步,即元数据保持一致,它们都将会和JournalNodes 守护进程通信。当 Active NN 执行任何有关命名空间的修改,它需要持久化到一半以上的 JournalNodes 上(通过 edits log 持久化存储),而 Standby NN 负责观察 edits log的变化,它能够读取从 JNs 中读取 edits 信息,并更新其内部的命名空间。一旦 Active NN出现故障,Standby NN 将会保证从 JNs 中读出了全部的 Edits,然后切换成 Active 状态。Standby NN 读取全部的 edits 可确保发生故障转移之前,是和 Active NN 拥有完全同步的命名空间状态。
为了提供快速的故障恢复,Standby NN 也需要保存集群中各个文件块的存储位置。为了实现这个,集群中所有的 Database 将配置好 Active NN 和 Standby NN 的位置,并向它们发送块文件所在的位置及心跳,如下图所示:

hadoop+zookeeper实现高可用集群-LMLPHP

在任何时候,集群中只有一个 NN 处于 Active 状态是极其重要的。否则,在两个 Active NN的状态下 NameSpace 状态将会出现分歧,这将会导致数据的丢失及其它不正确的结果。为了保证这种情况不会发生,在任何时间,JNs 只允许一个 NN 充当 writer。在故障恢复期间,将要变成 Active 状态的 NN 将取得 writer 的角色,并阻止另外一个 NN 继续处于 Active状态。
为了部署 HA 集群,你需要准备以下事项:
(1)、NameNode machines:运行 Active NN 和 Standby NN 的机器需要相同的硬件配置;
(2)、JournalNode machines:也就是运行 JN 的机器。JN 守护进程相对来说比较轻量,所以这些守护进程可以可其他守护线程(比如 NN,YARN ResourceManager)运行在同一台机器上。在一个集群中,最少要运行 3 个 JN 守护进程,这将使得系统有一定的容错能力。当然,你也可以运行 3 个以上的 JN,但是为了增加系统的容错能力,你应该运行奇数个 JN(3、5、7 等),当运行 N 个 JN,系统将最多容忍(N-1)/2 个 JN 崩溃。在 HA 集群中,Standby NN 也执行 namespace 状态的 checkpoints,所以不必要运行Secondary NN、CheckpointNode 和 BackupNode;事实上,运行这些守护进程是错误的

注意:Zookeeper 集群至少三台,总节点数为奇数个。

#######################hdfs高可用######################

一、配置zookeeper

1.新开一个服务器server5并安装nfs-util,:

[root@server5 ~]# yum install nfs-utils -y

2.新建hadoop用户:

[root@server5 ~]# useradd -u 800 hadoop

3.然后在五个服务端开启nfs服务,在server2、server3、server4、server5端将172.25.17.1:/home/hadoop目录挂载到本机/home/hadoop目录下

[root@server5 ~]# /etc/init.d/rpcbind start
[root@server5 ~]# /etc/init.d/nfs start
[root@server5 ~]# mount 172.25.17.1:/home/hadoop/ /home/hadoop/

hadoop+zookeeper实现高可用集群-LMLPHP

4.为了实验环境的干净,在五个服务端将之前的环境清理(不是必须):

[hadoop@server5 ~]$ rm -fr /tmp/*

5.在server1端,切换到hadoop用户,解压zookeeper安装包并将zoo_sample.cfg复制为zoo.cfg文件:
由于其他主机都使用了server1端的nfs文件系统,所以在server1端根目录下的hadoop目录里的所有操作,都会同步到其他4台主机里,也就是说5台机器的/home/hadoop目录内容完全一致。

[root@server1 ~]# su - hadoop
[hadoop@server1 ~]$ tar zxf zookeeper-3.4.9.tar.gz
[hadoop@server1 ~]$ cd zookeeper-3.4.9/conf
[hadoop@server1 conf]$ cp zoo_sample.cfg zoo.cfg

hadoop+zookeeper实现高可用集群-LMLPHP

编辑zoo.cfg文件,写入集群的三台设备:

hadoop+zookeeper实现高可用集群-LMLPHP

6.在三个集群节点:

各节点配置文件相同,并且需要在/tmp/zookeeper 目录中创建 myid 文件,写入一个唯一的数字,取值范围在 1-255。比如:172.25.45.2 节点的 myid 文件写入数字“1”,此数字与配置文件中的定义保持一致,(server.1=172.25.0.2:2888:3888)其它节点依次类推

hadoop+zookeeper实现高可用集群-LMLPHP

hadoop+zookeeper实现高可用集群-LMLPHP

hadoop+zookeeper实现高可用集群-LMLPHP

7.在各节点启动服务 发现server3为leader

在server2上:
[hadoop@server2 ~]$ cd zookeeper-3.4.9
[hadoop@server2 zookeeper-3.4.9]$ bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /home/hadoop/zookeeper-3.4.9/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[hadoop@server2 zookeeper-3.4.9]$ bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/hadoop/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode: follower
在server3上
[hadoop@server3 ~]$ cd zookeeper-3.4.9
[hadoop@server3 zookeeper-3.4.9]$ bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /home/hadoop/zookeeper-3.4.9/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[hadoop@server3 zookeeper-3.4.9]$ bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/hadoop/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode: leader
在server4上
[hadoop@server4 ~]$ cd zookeeper-3.4.9
[hadoop@server4 zookeeper-3.4.9]$  bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /home/hadoop/zookeeper-3.4.9/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[hadoop@server4 zookeeper-3.4.9]$ bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/hadoop/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode: follower

二、配置hadoop

在server1端:

1.编辑cpre-site.xml文件

[hadoop@server1 ~]$ cd hadoop/etc/hadoop/
[hadoop@server1 hadoop]$ vim core-site.xml  #指定hdfs的namenode为masters 指定zookeeper集群主机地址

hadoop+zookeeper实现高可用集群-LMLPHP

2.编辑hdfs-site.xml文件:

[hadoop@server1 hadoop]$ vim hdfs-site.xml
 17 <!-- Put site-specific property overrides in this file. -->
 18
 19 <configuration>
 20       <property>
 21          <name>dfs.replication</name>
 22          <value>3</value>
 23       </property>
 24 指定 hdfs 的 nameservices 为 masters,和 core-site.xml 文件中的设置保持一致
 25       <property>
 26           <name>dfs.nameservices</name>
 27           <value>masters</value>
 28       </property>
 29 masters 下面有两个 namenode 节点,分别是 h1 和 h2 (名称可自定义)
 30       <property>
 31            <name>dfs.ha.namenodes.masters</name>
 32            <value>h1,h2</value>
 33       </property>
 34 指定 h1 节点的 rpc 通信地址
 35       <property>
 36            <name>dfs.namenode.rpc-address.masters.h1</name>
 37            <value>172.25.45.1:9000</value>
 38       </property>
 39 指定 h1 节点的 http 通信地址
 40       <property>
 41             <name>dfs.namenode.http-address.masters.h1</name>
 42             <value>172.25.45.1:50070</value>
 43       </property>
 44 指定 h2 节点的 rpc 通信地址
 45       <property>
 46             <name>dfs.namenode.rpc-address.masters.h2</name>
 47             <value>172.25.45.5:9000</value>
 48       </property>
 49 指定 h2 节点的 http 通信地址
 50       <property>
 51             <name>dfs.namenode.http-address.masters.h2</name>
 52             <value>172.25.45.5:50070</value>
 53       </property>
 54 指定 NameNode 元数据在 JournalNode 上的存放位置
 55       <property>
 56          <name>dfs.namenode.shared.edits.dir</name>
 57          <value>qjournal://172.25.45.2:8485;172.25.45.3:8485;172.25.45.4:8485/masters</value>
 58       </property>
 59 指定 JournalNode 在本地磁盘存放数据的位置
 60       <property>
 61            <name>dfs.journalnode.edits.dir</name>
 62            <value>/tmp/journaldata</value>
 63       </property>
 64 开启 NameNode 失败自动切换
 65       <property>
 66             <name>dfs.ha.automatic-failover.enabled</name>
 67             <value>true</value>
 68        </property>
 69 配置失败自动切换实现方式
 70        <property>
 71           <name>dfs.client.failover.proxy.provider.masters</name>
 72       <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxy
Provider</value>
 73        </property>
 74 配置隔离机制方法,每个机制占用一行
 75        <property>
 76            <name>dfs.ha.fencing.methods</name>
 77            <value>
 78            sshfence
 79            shell(/bin/true)
 80            </value>
 81        </property>
 82 使用 sshfence 隔离机制时需要 ssh 免密码
 83        <property>
 84               <name>dfs.ha.fencing.ssh.private-key-files</name>
 85               <value>/home/hadoop/.ssh/id_rsa</value>
 86        </property>
 87 配置 sshfence 隔离机制超时时间
 88        <property>
 89              <name>dfs.ha.fencing.ssh.connect-timeout</name>
 90              <value>30000</value>
 91        </property>
 92 </configuration>

3.编辑文件slaves:

[hadoop@server1 hadoop]$ vim slaves

hadoop+zookeeper实现高可用集群-LMLPHP

4. 启动 hdfs 集群(按顺序启动)
1)在三个 DN 上依次启动 zookeeper 集群

[hadoop@server2 zookeeper-3.4.9]$ bin/zkServer.sh start

2)在三个 DN 上依次启动 journalnode(第一次启动 hdfs 必须先启动 journalnode)

cd /home/hadoop/hadoop

在server2上

[hadoop@server2 hadoop]$  sbin/hadoop-daemon.sh start journalnode
starting journalnode, logging to /home/hadoop/hadoop-2.7.3/logs/hadoop-hadoop-journalnode-server2.out
[hadoop@server2 hadoop]$ jps
1714 Jps
1664 JournalNode
1535 QuorumPeerMain

 

在server3上

[hadoop@server3 hadoop]$  sbin/hadoop-daemon.sh start journalnode
starting journalnode, logging to /home/hadoop/hadoop-2.7.3/logs/hadoop-hadoop-journalnode-server3.out
[hadoop@server3 hadoop]$ jps
1701 Jps
1651 JournalNode
1543 QuorumPeerMain

在server4上

[hadoop@server4 hadoop]$  sbin/hadoop-daemon.sh start journalnode
starting journalnode, logging to /home/hadoop/hadoop-2.7.3/logs/hadoop-hadoop-journalnode-server4.out
[hadoop@server4 hadoop]$ jps
1475 QuorumPeerMain
1600 JournalNode
1651 Jps

3)在server1格式化 HDFS 集群
Namenode 数据默认存放在/tmp,需要把数据拷到 h2

[hadoop@server1 hadoop]$ bin/hdfs namenode -format
[hadoop@server1 hadoop]$ scp -r /tmp/hadoop-hadoop 172.25.45.5:/tmp

hadoop+zookeeper实现高可用集群-LMLPHP

hadoop+zookeeper实现高可用集群-LMLPHP

4) 格式化 zookeeper (只需在 h1 上执行即可)

[hadoop@server1 hadoop]$ bin/hdfs zkfc -formatZK

hadoop+zookeeper实现高可用集群-LMLPHP

5)启动 hdfs 集群(只需在 h1 上执行即可)

[hadoop@server1 hadoop]$ sbin/start-dfs.sh 

hadoop+zookeeper实现高可用集群-LMLPHP

6) 查看各节点状态 

server1:
[hadoop@server1 hadoop]$ jps
12372 Jps
7050 DFSZKFailoverController
12332 NameNode
server2:
[hadoop@server2 hadoop]$ jps
1664 JournalNode
2325 Jps
1535 QuorumPeerMain
2212 DataNode
server3:
[hadoop@server3 hadoop]$ jps
1918 Jps
1651 JournalNode
1755 DataNode
1543 QuorumPeerMain
server4:
[hadoop@server4 hadoop]$ jps
2050 DataNode
1475 QuorumPeerMain
1600 JournalNode
2152 Jps
server5:
[hadoop@server5 dfs]$ jps
1306 DFSZKFailoverController
1511 Jps
1376 NameNode

测试:

发现server1为active server5为stanby

hadoop+zookeeper实现高可用集群-LMLPHP

 

hadoop+zookeeper实现高可用集群-LMLPHP

server1端杀掉namennode进程:

hadoop+zookeeper实现高可用集群-LMLPHP

杀掉 h1主机的 namenode 进程后依然可以访问,此时 h12转为 active 状态接管 namenode

刷新发现active跳到serverr5上:实现高可用

hadoop+zookeeper实现高可用集群-LMLPHP

重新开启server1的namenode:

[hadoop@server1 hadoop]$ sbin/hadoop-daemon.sh start namenode
starting namenode, logging to /home/hadoop/hadoop-2.7.3/logs/hadoop-hadoop-namenode-server1.out

刷新发现server1变成stanby

hadoop+zookeeper实现高可用集群-LMLPHP

 

######################## yarn 的高可用:######################

1. 编辑 mapred-site.xml 文件    指定 yarn 为 MapReduce 的框架

[hadoop@server1 hadoop]$ cd /home/hadoop/hadoop/etc/hadoop/
[hadoop@server1 hadoop]$ vim mapred-site.xml

hadoop+zookeeper实现高可用集群-LMLPHP

2.编辑 yarn-site.xml 文件

[hadoop@server1 hadoop]$ vim yarn-site.xml 
 15<configuration>
   配置可以在 nodemanager 上运行 mapreduce 程序
 16       <property>
 17                <name>yarn.nodemanager.aux-services</name>
 18                <value>mapreduce_shuffle</value>
 19       </property>
  激活 RM 高可用
 20        <property>
 21                <name>yarn.resourcemanager.ha.enabled</name>
 22                <value>true</value>
 23        </property>
  指定 RM 的集群 id
 24        <property>
 25                <name>yarn.resourcemanager.cluster-id</name>
 26                <value>RM_CLUSTER</value>
 27        </property>
  定义 RM 的节点
 28        <property>
 29                <name>yarn.resourcemanager.ha.rm-ids</name>
 30                <value>rm1,rm2</value>
 31        </property>
  指定 RM1 的地址
 32        <property>
 33                <name>yarn.resourcemanager.hostname.rm1</name>
 34                <value>172.25.45.1</value>
 35        </property>
  指定 RM2 的地址
 36        <property>
 37                <name>yarn.resourcemanager.hostname.rm2</name>
 38                <value>172.25.45.5</value>
 39        </property>
  激活 RM 自动恢复
 40        <property>
 41                <name>yarn.resourcemanager.recovery.enabled</name>
 42                <value>true</value>
 43        </property>
  配置 RM 状态信息存储方式,有 MemStore 和 ZKStore
 44        <property>
 45                <name>yarn.resourcemanager.store.class</name>
 46              <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
 48        </property>
  配置为 zookeeper 存储时,指定 zookeeper 集群的地址
 49        <property>
 50                <name>yarn.resourcemanager.zk-address</name>
 51                <value>172.25.45.2:2181,172.25.45.3:2181,172.25.45.4:2181</value>
 52        </property>
 53 <!-- Site specific YARN configuration properties -->
 54
 55 </configuration>

3.启动 yarn 服务

[hadoop@server1 hadoop]$ sbin/start-yarn.sh
[hadoop@server1 hadoop]$ jps

hadoop+zookeeper实现高可用集群-LMLPHP

hadoop+zookeeper实现高可用集群-LMLPHP

RM2 上需要手动启动:

[hadoop@server5 hadoop]$ sbin/yarn-daemon.sh start resourcemanager
[hadoop@server5 hadoop]$ jps

hadoop+zookeeper实现高可用集群-LMLPHP

hadoop+zookeeper实现高可用集群-LMLPHP

最好是把 RM 与 NN 分离运行,这样可以更好的保证程序的运行性能。

4.测试 yarn 故障切换

先在浏览器中分别输入172.25.45.1:8088  172.25.45.5:8088

发现server1为active server5为stanby

hadoop+zookeeper实现高可用集群-LMLPHP

hadoop+zookeeper实现高可用集群-LMLPHP

在server1中:

hadoop+zookeeper实现高可用集群-LMLPHP

浏览器中刷新看是否跳到server5上:

hadoop+zookeeper实现高可用集群-LMLPHP

hadoop+zookeeper实现高可用集群-LMLPHP

主备切换原理:
创建锁节点 在 ZooKeeper 上会有一个/yarn-leader-election/appcluster-yarn 的锁节点,所有 的 ResourceManager 在 启 动 的 时 候 , 都 会 去 竞 争 写 一 个 Lock 子 节 点 :/yarn-leader-election/appcluster-yarn/ActiveBreadCrumb,该节点是临时节点。ZooKeepr 能够为 我 们 保 证 最 终 只 有 一 个 ResourceManager 能 够 创 建 成 功 。 创 建 成 功 的 那 个ResourceManager 就切换为 Active 状态,没有成功的那些 ResourceManager 则切换为 Standby状态。

#####################hbase分布式部署############################

1.hbase 配置

[hadoop@server1 ~]$ tar zxf hbase-1.2.4-bin.tar.gz
[hadoop@server1 ~]$ cd /home/hadoophbase-1.2.4/conf
[hadoop@server1 conf]$ vim hbase-env.sh
  27 export JAVA_HOME=/home/hadoop/java    ##指定 jdk
  128 export HBASE_MANAGES_ZK=false  ##默认值时 true,hbase 在启动时自动开启zookeeper,如需自己维护zookeeper集群需设置为false
  129 export HADOOP_HOME=/home/hadoop/hadoop  ##指定hadoop目录,否则hbase无法识别hdfs集群配置。

2.编辑hbase-site.xml文件:

[hadoop@server1 conf]$ vim hbase-site.xml
<configuration>
  指定 region server 的共享目录,用来持久化 HBase。这里指定的 HDFS 地址
是要跟 core-site.xml 里面的 fs.defaultFS 的 HDFS 的 IP 地址或者域名、端口必须一致
       <property>
       <name>hbase.rootdir</name>
       <value>hdfs://masters/hbase</value>
       </property>
  启用 hbase 分布式模式
       <property>
       <name>hbase.cluster.distributed</name>
       <value>true</value>
       </property>
       <property>
  Zookeeper 集群的地址列表,用逗号分割。默认是 localhost,是给伪分布式用
的。要修改才能在完全分布式的情况下使用
       <name>hbase.zookeeper.quorum</name>
       <value>172.25.45.2,172.25.45.3,172.25.45.4</value>
       </property>
  指定数据拷贝 2 份,hdfs 默认是 3 份
       <property>
       <name>dfs.replication</name>
       <value>2</value>
       </property>
  指定 hbase 的 master
       <property><name>hbase.master</name>
       <value>h1</value>
       </property>
</configuration>

3.vim regionservers

[hadoop@server1 conf]$ vim regionservers 

hadoop+zookeeper实现高可用集群-LMLPHP

4.启动 hbase
主节点运行:

[hadoop@server1 ~]$ cd hbase-1.2.4
[hadoop@server1 hbase-1.2.4]$ bin/start-hbase.sh
[hadoop@server1 hbase-1.2.4]$ jps

hadoop+zookeeper实现高可用集群-LMLPHP
备节点运行:

[hadoop@server5 hbase-1.2.4]$ bin/hbase-daemon.sh start master
[hadoop@server5 hbase-1.2.4]$ jps

hadoop+zookeeper实现高可用集群-LMLPHP

HBase Master 默认端口时 16000,还有个 web 界面默认在 Master 的 16010 端口上,HBase RegionServers 会默认绑定 16020 端口,在端口 16030 上有一个展示信息的界面

测试:
[hadoop@server1 hbase]$ bin/hbase shell

[hadoop@server5 hadoop]$ bin/hdfs dfs -ls /

在主节点上 kill 掉 HMaster 进程后查看故障切换:

11-20 18:45