官方文档翻译,官方链接。
翻译水平有限,且以学习为主,请谅解和提意见。
转载请注明出处!!!
自动failover
介绍
前面详细说明了如何配置手工failover。在那种模式下,系统不能自动地触发将NameNode从active状态failover到standby状态,即使active节点已经失败了。这部分将讲述如何配置、部署自动failover。
组件
自动failover需要增加两个新的组件到HDFS上:一个是Zookeeper quorum(仲裁),另一个是ZKFailoverController进程(简称ZKFC)。
Apache Zookeeper是一个高可用的服务,对于小规模数据协调,通知客户端数据变化,监控客户端失败。自动failover的实现是基于ZK以下的事实:
- Failure detection - 集群中的每个NameNode机器在ZK上保持持久化会话。如果机器崩溃,ZK会话过期,通知其它NameNode有一个failover将被触发。
- Active NameNode election - ZK提供一个简单机制,选举出唯一的一个节点作为active。如果当前的active NameNode崩溃,另一个节点可能在ZK持有特定的互斥型锁,表名它将成为下一个active。
ZKFC是一个新的组件,是一个ZK客户端,也监控和管理NameNode的状态。NameNode运行的所在的每个机器也要运行一个ZKFC,ZKFC负责:
- Health monitoring(健康监控) - ZKFC使用健康检查命令定期地ping本地NameNode。只要NameNode及时响应一个健康状态,ZKFC则确认节点健康。如果节点已经崩溃、冻结、其它不健康状态,健康监控器将标记它为不健康。
- ZooKeeper session management(ZK会话管理)- 当本地NameNode健康,ZKFC在ZK上持有一个打开的会话。如果本地NameNode是active的,它持有指定的znode锁。这个锁用于ZK支持“短暂”的节点,如果会话过期,锁节点将自动被删除。
- ZooKeeper-based election(基于ZK的选举) - 如果本地NameNode健康,ZKFC看到当前没有其它节点控制znode锁,它自己将尝试获取这个所有。如果成功,则它胜选,负责运行一个failover,使本地NameNode成为active。failover进程类似于上面描述的手工failover:首先,如果必要前一个active被fencing了,然后,本地的NameNode转换为active状态。
对应自动failover设计上的更多描述,到Apache HDFS JIRA上,参考设计文档HDFS-2185。
部署ZK
在典型的部署中,ZK守护进程被配置、运行在3或5个节点上。由于ZK自身资源需求,分配ZK节点的硬件资源可以与HDFS NameNode的机器配置一样。许多人选择在同一节点上部署3个ZK进程作为YARN ResourceManager。配置ZK节点将数据存储在独立磁盘驱动器上。
安装ZK超出本文档范围。
开始前
配置自动failover前,需要停掉集群。目前当集群运行时,还不能从一个手工failover转换到自动failover。
配置自动failover
自动failover需要增加两个新的配置参数。
在hdfs-site.xml中,增加:
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
在core-site.xml文中,为了自动failover需要集群设置这个:
<property>
<name>ha.zookeeper.quorum</name>
<value>zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181</value>
</property>
这个主机端口对列表运行着ZK服务。
使用前文描述的参数,这些配置可以在每个nameservice上使用nameservice ID作为后缀进行设置。例如,集群使用联邦机制时,通过设置dfs.ha.automatic-failover.enabled.my-nameservice-id参数,可以准确地配置某一个nameservice使用自动failover。
在ZK中,初始化HA状态
这些配置键添加后,下一步是在ZK中初始化必要的状态。在其中一个NameNode主机,执行如下命令,完成这个初始化。
[hdfs]$ $HADOOP_PREFIX/bin/hdfs zkfc -formatZK
这个命令将在ZK中创建一个znode,用于存储自动failover所需要的数据。
使用start-dfs.sh启动集群
由于已经配置了自动failover,执行start-dfs.sh脚本将在运行NameNode的节点上启动一个ZKFC守护进程。当ZKFC启动,它们将自动选择一个NameNode成为active。
手工启动集群
如果手工管理集群,需要手工在运行NameNode的节点上启动ZFKC进程。使用如下命令启动:
[hdfs]$ $HADOOP_PREFIX/sbin/hadoop-daemon.sh --script $HADOOP_PREFIX/bin/hdfs start zkfc
安全访问ZK
如果运行一个带安全机制的集群,或许想确保存储在ZK上的信息也是安全的。阻止恶意客户端篡改ZK中的元数据,触发一个错误的failover。
为了在ZK中保护信息,需要在core-site.xml文件添加如下:
<property>
<name>ha.zookeeper.auth</name>
<value>@/path/to/zk-auth.txt</value>
</property>
<property>
<name>ha.zookeeper.acl</name>
<value>@/path/to/zk-acl.txt</value>
</property>
请初一这些值里的'@'字符 - 这个表示配置不是内联的,而是指向磁盘上的文件。
第一个配置文件是指定一个ZK认证列表,与ZK CLI使用相同的格式,格式如下:
digest:hdfs-zkfcs:mypassword
hdfs-zkfcs是一个ZK用户名,mypassword使用密码串。
接下来,产生一个与这个认证一致的ZK ACL。使用如下命令:
[hdfs]$ java -cp $ZK_HOME/lib/*:$ZK_HOME/zookeeper-3.4.2.jar org.apache.zookeeper.server.auth.DigestAuthenticationProvider hdfs-zkfcs:mypassword
output: hdfs-zkfcs:mypassword->hdfs-zkfcs:P/OQvnYyU/nF/mGYvB/xurX8dYs=
复制'->'后面的字符串,粘贴到zk-acls.txt,前缀加上'digest:'。例如:
digest:hdfs-zkfcs:vlUvLnd8MlacsE80rDuu6ONESbM=:rwcda
为了让这些ACL生效,需要重新运行zkfc -formatZK命令。
这样做之后,可以验证的acl,ZK CLI如下:
[zk: localhost:2181(CONNECTED) 1] getAcl /hadoop-ha
'digest,'hdfs-zkfcs:vlUvLnd8MlacsE80rDuu6ONESbM=
: cdrwa
验证自动failover
自动failover部署完成,既可以测试了。
首先定位active NameNode。可以通过访问NameNode的Web页面,来得到active NameNode。
定位到active NameNode,可以在这个节点上制造一个失败。例如,可以执行kill -9 <pid of NN> 来模拟JVM崩溃。或者关机,或者拔掉网线模拟不同的故障。期望测试的故障触发后,其它的NameNode将在几秒内自动成为active的。故障检测和触发故障转移所需的时间取决于ha.zookeeper.session-timeout.ms**的配置,默认5秒。
如果测试没有成功,可能有一个错误配置存在。检查zkfc守护进程以及NameNode守护进程的日志,进一步诊断问题。
自动failover的FAQ
Is it important that I start the ZKFC and NameNode daemons in any particular order?(ZKFC和NameNode有启动顺序吗?)
没有,在指定的节点上,可以在相应的NameNode启动之前或之后,启动ZKFC。What additional monitoring should I put in place?(额外的监控我应该放在什么地方?)
需要将空运行NameNode的每台主机,确保ZKFC运行。例如ZKFC意外退出等ZK异常,需要重启ZKFC,确保系统的自动failover。
另外,还有监控每个ZK Quorum服务器。如果ZK崩溃,自动failover将不可用。What happens if ZooKeeper goes down?(如果ZK停了,发生什么?)
如果ZK崩溃,将没有自动failover可以触发了。然而,HDFS将继续运行,不受影响。当ZK重启,HDFS将重新连接。Can I designate one of my NameNodes as primary/preferred?(可以指派一个NameNode为首选active的吗?)
不可以,当前不支持。无论哪个NameNode首先启动都将成为active的。你可以选择启动集群的顺序,先启动你首选的节点。How can I initiate a manual failover when automatic failover is configured?(当自动failover配置了,如何进行一次手工failover?)
即使配置了自动failover,也可以使用hdfs haadmin命令进行一次手工failover,执行是一样的。
HA HDFS升级、终止、回滚
在HDFS版本之间迁移,有时新版本软件可以很简单的安装和重启集群。然而,有时升级HDFS版本需要更改磁盘数据。在这种情况下,安装新版本软件后,必须使用HDFS的升级/终止/回滚过程进行处理。在HA环境中,这个过程更复杂;因为NN依赖的磁盘元数据是分布定义的。
执行HA升级
过程如下:
- 正常关闭所有NameNode,安装新版软件。
- 启动所有JN。请注意,重要的是,当执行升级、回滚、终止操作时,所有的JN都在运行。如果在运行这些操作时,任何JN停止,操作将会失败。
- 使用'-upgrade'启动一个NN。
- 在启动中,这个NN不能进入standby状态。而是要立即进入active状态,在它的本地存储目录执行升级,且在共享的编辑日志执行升级。
- 此时另一个NN没有与已经升级的NN同步。为了使这个NN同步和再次进行HA设置,需要在这个NameNode节点上,使用'-bootstrapStandby'参数重新引导NameNode启动。第二个NN使用'-upgrade'将报错。
注意,如果在终止或者回滚这个升级前,任何时候打算重启NNs,比如正常启动NNs,不要有任何特殊的启动参数。
终止HA升级
当NNs正在运行且一个是active的时,使用`hdfs dfsadmin -finalizeUpgrade'进行终止升级。此时active NN将执行共享日志终止,NN的本地存储目录包含之前FS状态将删除它的本地状态。
执行回滚
首先,两个NN将关闭。在NN上运行回滚开始的升级过程,在本地目录、共享日志、NFS/JNs执行回滚。
之后,这个NN启动,另一个NN使用`-bootstrapStandby'启动,使两个NN同步到回滚之前的文件系统状态。