在上一篇博客的基础上做这次实验
系统环境: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作为集群服务器
ip |
主机名 |
角色 |
172.25.45.1 | server1.example.com | NameNode DFSZKFailoverController ResourceManager |
172.25.45.2 | server2.example.com | NameNode DFSZKFailoverController ResourceManager |
172.25.45.3 | server3.example.com | NameNode DFSZKFailoverController ResourceManager |
172.25.45.4 | server4.example.com | NameNode DFSZKFailoverController ResourceManager |
172.25.45.5 | server5.example.com | NameNode DFSZKFailoverController ResourceManager |
在典型的 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 的位置,并向它们发送块文件所在的位置及心跳,如下图所示:
在任何时候,集群中只有一个 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 集群至少三台,总节点数为奇数个。
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/
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
编辑zoo.cfg文件,写入集群的三台设备:
6.在三个集群节点:
各节点配置文件相同,并且需要在/tmp/zookeeper 目录中创建 myid 文件,写入一个唯一的数字,取值范围在 1-255。比如:172.25.45.2 节点的 myid 文件写入数字“1”,此数字与配置文件中的定义保持一致,(server.1=172.25.0.2:2888:3888)其它节点依次类推。
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
在server1端:
1.编辑cpre-site.xml文件
[hadoop@server1 ~]$ cd hadoop/etc/hadoop/
[hadoop@server1 hadoop]$ vim core-site.xml #指定hdfs的namenode为masters 指定zookeeper集群主机地址
2.编辑hdfs-site.xml文件:
[hadoop@server1 hadoop]$ vim hdfs-site.xml
17
18
19
20
21 dfs.replication
22 3
23
24 指定 hdfs 的 nameservices 为 masters,和 core-site.xml 文件中的设置保持一致
25
26 dfs.nameservices
27 masters
28
29 masters 下面有两个 namenode 节点,分别是 h1 和 h2 (名称可自定义)
30
31 dfs.ha.namenodes.masters
32 h1,h2
33
34 指定 h1 节点的 rpc 通信地址
35
36 dfs.namenode.rpc-address.masters.h1
37 172.25.45.1:9000
38
39 指定 h1 节点的 http 通信地址
40
41 dfs.namenode.http-address.masters.h1
42 172.25.45.1:50070
43
44 指定 h2 节点的 rpc 通信地址
45
46 dfs.namenode.rpc-address.masters.h2
47 172.25.45.5:9000
48
49 指定 h2 节点的 http 通信地址
50
51 dfs.namenode.http-address.masters.h2
52 172.25.45.5:50070
53
54 指定 NameNode 元数据在 JournalNode 上的存放位置
55
56 dfs.namenode.shared.edits.dir
57 qjournal://172.25.45.2:8485;172.25.45.3:8485;172.25.45.4:8485/masters
58
59 指定 JournalNode 在本地磁盘存放数据的位置
60
61 dfs.journalnode.edits.dir
62 /tmp/journaldata
63
64 开启 NameNode 失败自动切换
65
66 dfs.ha.automatic-failover.enabled
67 true
68
69 配置失败自动切换实现方式
70
71 dfs.client.failover.proxy.provider.masters
72 org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxy
Provider
73
74 配置隔离机制方法,每个机制占用一行
75
76 dfs.ha.fencing.methods
77
78 sshfence
79 shell(/bin/true)
80
81
82 使用 sshfence 隔离机制时需要 ssh 免密码
83
84 dfs.ha.fencing.ssh.private-key-files
85 /home/hadoop/.ssh/id_rsa
86
87 配置 sshfence 隔离机制超时时间
88
89 dfs.ha.fencing.ssh.connect-timeout
90 30000
91
92
3.编辑文件slaves:
[hadoop@server1 hadoop]$ vim slaves
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
4) 格式化 zookeeper (只需在 h1 上执行即可)
[hadoop@server1 hadoop]$ bin/hdfs zkfc -formatZK
5)启动 hdfs 集群(只需在 h1 上执行即可)
[hadoop@server1 hadoop]$ sbin/start-dfs.sh
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
server1端杀掉namennode进程:
杀掉 h1主机的 namenode 进程后依然可以访问,此时 h12转为 active 状态接管 namenode
刷新发现active跳到serverr5上:实现高可用
重新开启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
1. 编辑 mapred-site.xml 文件 指定 yarn 为 MapReduce 的框架
[hadoop@server1 hadoop]$ cd /home/hadoop/hadoop/etc/hadoop/
[hadoop@server1 hadoop]$ vim mapred-site.xml
2.编辑 yarn-site.xml 文件
[hadoop@server1 hadoop]$ vim yarn-site.xml
15
配置可以在 nodemanager 上运行 mapreduce 程序
16
17 yarn.nodemanager.aux-services
18 mapreduce_shuffle
19
激活 RM 高可用
20
21 yarn.resourcemanager.ha.enabled
22 true
23
指定 RM 的集群 id
24
25 yarn.resourcemanager.cluster-id
26 RM_CLUSTER
27
定义 RM 的节点
28
29 yarn.resourcemanager.ha.rm-ids
30 rm1,rm2
31
指定 RM1 的地址
32
33 yarn.resourcemanager.hostname.rm1
34 172.25.45.1
35
指定 RM2 的地址
36
37 yarn.resourcemanager.hostname.rm2
38 172.25.45.5
39
激活 RM 自动恢复
40
41 yarn.resourcemanager.recovery.enabled
42 true
43
配置 RM 状态信息存储方式,有 MemStore 和 ZKStore
44
45 yarn.resourcemanager.store.class
46 org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore
48
配置为 zookeeper 存储时,指定 zookeeper 集群的地址
49
50 yarn.resourcemanager.zk-address
51 172.25.45.2:2181,172.25.45.3:2181,172.25.45.4:2181
52
53
54
55
3.启动 yarn 服务
[hadoop@server1 hadoop]$ sbin/start-yarn.sh
[hadoop@server1 hadoop]$ jps
RM2 上需要手动启动:
[hadoop@server5 hadoop]$ sbin/yarn-daemon.sh start resourcemanager
[hadoop@server5 hadoop]$ jps
最好是把 RM 与 NN 分离运行,这样可以更好的保证程序的运行性能。
4.测试 yarn 故障切换
先在浏览器中分别输入172.25.45.1:8088 172.25.45.5:8088
发现server1为active server5为stanby
在server1中:
浏览器中刷新看是否跳到server5上:
主备切换原理:
创建锁节点 在 ZooKeeper 上会有一个/yarn-leader-election/appcluster-yarn 的锁节点,所有 的 ResourceManager 在 启 动 的 时 候 , 都 会 去 竞 争 写 一 个 Lock 子 节 点 :/yarn-leader-election/appcluster-yarn/ActiveBreadCrumb,该节点是临时节点。ZooKeepr 能够为 我 们 保 证 最 终 只 有 一 个 ResourceManager 能 够 创 建 成 功 。 创 建 成 功 的 那 个ResourceManager 就切换为 Active 状态,没有成功的那些 ResourceManager 则切换为 Standby状态。
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
指定 region server 的共享目录,用来持久化 HBase。这里指定的 HDFS 地址
是要跟 core-site.xml 里面的 fs.defaultFS 的 HDFS 的 IP 地址或者域名、端口必须一致
hbase.rootdir
hdfs://masters/hbase
启用 hbase 分布式模式
hbase.cluster.distributed
true
Zookeeper 集群的地址列表,用逗号分割。默认是 localhost,是给伪分布式用
的。要修改才能在完全分布式的情况下使用
hbase.zookeeper.quorum
172.25.45.2,172.25.45.3,172.25.45.4
指定数据拷贝 2 份,hdfs 默认是 3 份
dfs.replication
2
指定 hbase 的 master
hbase.master
h1
3.vim regionservers
[hadoop@server1 conf]$ vim regionservers
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@server5 hbase-1.2.4]$ bin/hbase-daemon.sh start master
[hadoop@server5 hbase-1.2.4]$ jps
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 进程后查看故障切换: