HA(High Available), 高可用,是保证业务连续性的有效解决方案, 通常通过设置备用节点的方式实现;
一般分为执行业务的称为活动节点(Active),和作为活动节点的一个备份的备用节点(Standby), 当活动节点出现问题, 导致正在运行的业务不能正常运行时, 备用节点此时就会侦测到, 并立即接替活动节点来执行业务, 从而实现业务的不中断或短
暂中断.
在 Active NN 和 Standby NN 之间设置一个共享的存储日志的地方, Active NN把 edit Log 写到这个共享的存储日志的地方, Standby NN 去读取日志然后执行,这样 Active 和 Standby NN 内存中的 HDFS 元数据保持着同步。一旦发生主从切换 Standby NN 可以尽快接管 Active NN 的工作
hadoop2.x 之后, Clouera 提出了 QJM/Qurom Journal Manager,这是一个基于 Paxos 算法(分布式一致性算法) 实现的 HDFS HA 方案,它给出了一种较好的解决思路和方案,QJM 主要优势如下:
不需要配置额外的高共享存储,降低了复杂度和维护成本。
消除 spof(单点故障)。
系统鲁棒性(Robust)的程度可配置、可扩展。
基本原理就是用 2N+1 台 JournalNode 存储 EditLog,每次写数据操作有>=N+1返回成功时即认为该次写成功,数据不会丢失了。
其中:
JournalNode
JournalNode 的作用是存储Active NN 的 EditLog, 并供Standby NN读取;
任何修改操作在 Active NN 上执行时, JournalNode 进程同时也会记录修改log到至少半数以上的 JN 中,这时 Standby NN 监测到 JN 里面的同步 log 发生变化了会读取 JN 里面的修改 log,然后同步到自己的目录镜像树里面,如下图:
当发生故障时, Active 的 NN 挂掉后, Standby NN 会在它成为 Active NN前,读取所有的 JN 里面的修改日志,这样就能高可靠的保证与挂掉的 NN 的目录镜像树一致,然后无缝的接替它的职责,维护来自客户端请求,从而达到一个高可用的目的。
在 HA 模式下, datanode 需要确保同一时间有且只有一个 NN 能命令 DN。 为此:
每个 NN 改变状态的时候,向 DN 发送自己的状态和一个序列号。DN 在运行过程中维护此序列号,当 failover 时,新的 NN 在返回 DN 心跳时会返回自己的active 状态和一个更大的序列号。 DN 接收到这个返回则认为该 NN 为新的active。如果这时原来的 active NN 恢复,返回给 DN 的心跳信息包含 active 状态和原来的序列号,这时 DN 就会拒绝这个 NN 的命令。
Failover Controller
FailoverController 部署在每个 NameNode 的节点上,作为一个单独的进程用来监视 NN 的健康状态。 FailoverController主要包括三个组件:
HealthMonitor: 监控 NameNode 是否处于 unavailable 或 unhealthy 状态。前通过RPC 调用 NN 相应的方法完成。
ActiveStandbyElector: 监控 NN 在 ZK 中的状态。
ZKFailoverController: 订阅 HealthMonitor 和 ActiveStandbyElector 的事件,并管理 NN 的状态,另外 zkfc 还负责解决 fencing(也就是脑裂问题)。
一个典型的 HA 集群,有两个 NN 组成,每个 NN 都有自己的 ZKFC 进程。
ZKFailoverController 主要职责:
健康监测: 周期性的向它监控的 NN 发送健康探测命令,从而来确定某个NameNode是否处于健康状态,如果机器宕机,心跳失败,那么 zkfc 就会标记它处于一个不健康的状态
会话管理: 如果 NN 是健康的, zkfc 就会在 zookeeper 中保持一个打开的会话,如果 NameNode 同时还是 Active 状态的,那么 zkfc 还会在 Zookeeper 中占有一个类型为短暂类型的 znode,当这个 NN 挂掉时,这个 znode 将会被删除,然后备用的NN 将会得到这把锁,升级为主 NN,同时标记状态为 Active; 当宕机的 NN 新启动时,它会再次注册 zookeper,发现已经有 znode 锁了,便会自动变为 Standby 状态,如此往复循环,保证高可靠,需要注意, 目前仅仅支持最多配置 2 个 NN
master 选举: 通过在 zookeeper 中维持一个短暂类型的 znode,来实现抢占式的锁机制,从而判断那个 NameNode 为 Active 状态
ResourceManager(简写为 RM)作为 Yarn 系统中的主控节点,负责整个系统的资源管理和调度,内部维护了各个应用程序的 ApplictionMaster 信息、NodeManager(简写为 NM)信息、 资源使用等。一旦发生故障,恢复时间较长,且会导致正在运行的 Application 丢失,影响范围较大。
从 Hadoop 2.4.0版本开始, Yarn 实现了 ResourceManager HA,在发生故障时自动 failover, 大大提高了服务的可靠性
由于资源使用情况和 NodeManager 信息都可以通过 NodeManager 的心跳机制重新构建出来,因此只需要对 ApplicationMaster 相关的信息进行持久化存储即可。
在一个典型的 HA 集群中,两台独立的机器被配置成 ResourceManger。在任意时间,有且只允许一个活动的 ResourceManger,另外一个备用。 切换分为两种方式:
手动切换:在自动恢复不可用时,管理员可用手动切换状态,或是从Active 到 Standby,或是从 Standby 到 Active。
自动切换:基于 Zookeeper,但是区别于 HDFS 的 HA, 2 个节点间无需配置额外的 ZFKC守护进程来同步数据。
本次部署3节点Hadoop HA集群
三台Linux主机需要:
修改主机名
node1, node2, node3
修改hosts文件配置好主机名与IP地址的映射关系(包括windows主机的hosts文件)
关闭防火墙
关闭防火墙: service iptables stop
关闭防火墙开机自启: chkconfig iptables off
设置好互相之间的ssh免密登录
生成密钥:
ssh-keygen -t rsa
按四下回车生成密钥
拷贝公钥到到三台主机(包括自己):
ssh-copy-id node1
ssh-copy-id node2
ssh-copy-id node3
并使用ssh 主机名
命令互相进行登录测试
同步时区(同步的阿里云)
yum install -y ntp
ntpdate ntp6.aliyun.com
安装好JDK, 配置好环境变量
(默认已经安装配置)
安装配置zooekeeper集群
(默认已经安装配置)
上传并解压 hadoop-2.7.4-with-centos-6.7.tar.gz
本次解压到了/export/server/下(路径可自定)
并在/export下创建路径data/hadoopdata
设置环境变量
vim /etc/profile
添加下面内容:
export HADOOP_HOME=/export/server/hadoop-2.7.4
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/sbin
source /etc/profile
修改Hadoop配置文件
Hadoop的配置文件在$HADOOP_HOME/etc/hadoop下
cd /export/server/hadoop-2.7.4/etc/hadoop
3.1 修改 hadoop-env.sh
vim hadoop-env.sh
配置JAVA_HOME:
export JAVA_HOME=/export/server/jdk1.8.0_181
3.2 修改core-site.xml
vim core-site.xml
fs.defaultFS
hdfs://cluster1
hadoop.tmp.dir
/export/data/hadoopdata
ha.zookeeper.quorum
node1:2181,node2:2181,node3:2181
3.3 修改hdfs-site.xml
vim hdfs-site.xml
dfs.nameservices
cluster1
dfs.ha.namenodes.cluster1
nn1,nn2
dfs.namenode.rpc-address.cluster1.nn1
node1:9000
dfs.namenode.http-address.cluster1.nn1
node1:50070
dfs.namenode.rpc-address.cluster1.nn2
node2:9000
dfs.namenode.http-address.cluster1.nn2
node2:50070
dfs.namenode.shared.edits.dir
qjournal://node1:8485;node2:8485;node3:8485/cluster1
dfs.journalnode.edits.dir
/export/data/hadoopdata/journaldata
dfs.ha.automatic-failover.enabled
true
dfs.client.failover.proxy.provider.cluster1
org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
dfs.ha.fencing.methods
sshfence
dfs.ha.fencing.ssh.private-key-files
/root/.ssh/id_rsa
dfs.ha.fencing.ssh.connect-timeout
30000
3.4 修改mapred-site.xml
cp mapred-site.xml.template mapred-site.xml
vim mapred-site.xml
mapreduce.framework.name
yarn
3.5 修改yarn-site.xml
vim yarn-site.xml
yarn.resourcemanager.ha.enabled
true
yarn.resourcemanager.cluster-id
yrc
yarn.resourcemanager.ha.rm-ids
rm1,rm2
yarn.resourcemanager.hostname.rm1
node1
yarn.resourcemanager.hostname.rm2
node2
yarn.resourcemanager.zk-address
node1:2181,node2:2181,node3:2181
yarn.nodemanager.aux-services
mapreduce_shuffle
3.6 修改slaves(slaves是指定子节点的位置)
vim slaves
node1
node2
node3
将配置好的hadoop拷贝到其他主机
scp -r /export/server/hadoop-2.7.4 root@node2:/export/server/
scp -r /export/server/hadoop-2.7.4 root@node3:/export/server/
格式化及启动
5.1 首先分别在三台主机上启动zookeeper集群
/export/server/zookeeper-3.4.7/bin/zkServer.sh start
查看集群状态:
/export/server/zookeeper-3.4.7/bin/zkServer.sh status
一个leader,两个follower, 启动正常
5.2 分别在三台主机上手动启动journalnode
hadoop-daemon.sh start journalnode
运行jps
命令检验, node1、node2、node3上多了JournalNode进程
5.3 格式化namenode
在node1上执行命令:
hdfs namenode -format
格式化后会在根据core-site.xml中的hadoop.tmp.dir配置生成个文件,这里我配置的是/export/data/hadoopdata
然后将/hadoop/hadoop-2.6.4/tmp拷贝到node2的/export/data/下。
scp -r /export/data/hadoopdata root@node2:/export/data/
5.4 格式化ZKFC(在node1上执行即可)
hdfs zkfc -formatZK
5.5 启动HDFS(在node1上执行)
start-dfs.sh
日志:
Starting namenodes on [node1 node2]
node1: starting namenode, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-namenode-node1.out
node2: starting namenode, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-namenode-node2.out
node3: starting datanode, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-datanode-node3.out
node2: starting datanode, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-datanode-node2.out
node1: starting datanode, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-datanode-node1.out
Starting journal nodes [node1 node2 node3]
node3: journalnode running as process 2804. Stop it first.
node2: journalnode running as process 2998. Stop it first.
node1: journalnode running as process 4281. Stop it first.
Starting ZK Failover Controllers on NN hosts [node1 node2]
node1: starting zkfc, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-zkfc-node1.out
node2: starting zkfc, logging to /export/server/hadoop-2.7.4/logs/hadoop-root-zkfc-node2.out
可以看到在
node1上启动了namenode, datanode, journalnode, zkfc
node2上启动的有namenode, datanode, journalnode, zkfc
node3上启动的有datanode, journalnode
5.6 启动yarn
在node1上执行:
start-yarn.sh
日志:
starting yarn daemons
starting resourcemanager, logging to /export/server/hadoop-2.7.4/logs/yarn-root-resourcemanager-node1.out
node3: starting nodemanager, logging to /export/server/hadoop-2.7.4/logs/yarn-root-nodemanager-node3.out
node2: starting nodemanager, logging to /export/server/hadoop-2.7.4/logs/yarn-root-nodemanager-node2.out
node1: starting nodemanager, logging to /export/server/hadoop-2.7.4/logs/yarn-root-nodemanager-node1.out
还有一个备用节点启动yarn,在node2上执行:
yarn-daemon.sh start resourcemanager
日志:
starting resourcemanager, logging to /export/server/hadoop-2.7.4/logs/yarn-root-resourcemanager-node2.out
5.7 运行jps
命令检验进程
node1:
2402 QuorumPeerMain
8243 ResourceManager
8360 NodeManager
4281 JournalNode
7673 DataNode
9930 Jps
7530 NameNode
8076 DFSZKFailoverController
node2:
5168 Jps
3696 DFSZKFailoverController
3540 DataNode
3477 NameNode
2998 JournalNode
2059 QuorumPeerMain
3773 NodeManager
4670 ResourceManager
node3:
2049 QuorumPeerMain
2804 JournalNode
4341 Jps
4073 DataNode
4201 NodeManager
启动正常!
验证HDFS HA
首先向hdfs上传一个文件
hadoop fs -put /root/1.txt /
查看
hadoop fs -ls /
-rw-r--r-- 3 root supergroup 1 2018-09-22 14:39 /1.txt
使用浏览器访问: http://node1:50070
node1的namenode状态为active!
查看hdfs根路径
可以看到刚才上传的文件
使用浏览器访问: http://node1:50070
可以看到node2的namenode状态为standby!
查看hdfs根路径:
可以发现namenode的备用节点(Standby)无法查看内容
当在node1上停止namenode进程后
kill -9 7530
通过浏览器访问: http://node1:50070 会发现无法访问
访问 http://node1:50070
可以看到node2的namenode状态变为active!
查看hdfs根路径也可以看到之前上传的文件 1.txt
在node1上重新启动namenode
hadoop-daemon.sh start namenode
通过浏览器访问:http://node1:50070 发现namenode状态变成了standby
验证验证YARN
使用浏览器访问 http://node1:8088/cluster, 成功进入页面
当访问http://node2:8088/cluster时, 会直接跳转到http://node1:8088/cluster
也可以执行一些mapreduce程序进行检验, 这里就不一一赘述了
至此搭建结束!