Stay hungry Stay foolish

HDFS高可用之QJM-04

Posted on By blue

目录



1、前言

本文写于2018年02月份,以当前HDFS版本2.9.0为主,主要参考为官方文档,其中加入了一些自己的理解,如有不对之处,还请多多指教,感谢!

本文介绍了使用日志管理器(QJM)使用了了HDFS高可用性(HA)功能以及如何配置和管理HA HDFS群集

本文档假定读者对HDFS集群中的通用组件和节点类型有一个大体的了解。有关详细信息,请参阅HDFS体系结构指南。

注意:使用Quorum Journal Manager或常规共享存储

本指南讨论如何使用Quorum Journal Manager(QJM)配置和使用HDFS HA,以共享活动和备用NameNode之间的edit logs 。有关如何使用NFS配置HDFS HA而不是QJM的信息,请参阅此指南

2、背景

在Hadoop 2.0.0之前,NameNode是HDFS集群中存在单点故障(SPOF)。每个群集只有一个NameNode,如果namenode机器或进程不可用,整个群集将不可用,直到NameNode重新启动或在单独的计算机上启动为止。

这在以下两个主要方面影响了HDFS集群的总体可用性:

  • 在计划外事件(例如机器崩溃)的情况下,直有等到操作员重新启动NameNode后,群集才可用。
  • 计划的维护事件(如NameNode计算机上的软件或硬件升级)将导致群集停机一段时间。

HDFS高可用性功能,是通过提供在具有热备份的主动/被动配置,在同一集群中运行两个NameNode来解决上述问题。这允许在计算机崩溃的情况下快速故障转移到新的NameNode,或者为维护目的而进行的正常故障转移。

3、架构

在典型的HA群集中,两台独立的机器配置为NameNode。在任何时候,只有一个NameNodes处于Active状态,另一个处于Standby状态。活动的NameNode负责群集中的所有客户端操作,而备用服务器仅充当从服务器,如果有必要,进行维护足够的状态以提供快速故障转移。

为了使备用节点保持其与活动节点的状态同步,两个节点都与一组称为“日志节点”(JournalNodes,简称:JN)的独立守护进程进行通信。当活动节点执行任何名称空间修改时,它会将修改记录持久记录到大多数这些JN中。备用节点能够读取来自JN的编辑,并不断监视它们,以更改编辑日志(edit log)。当备用节点看到编辑时,它将会同步变化到它自己的名称空间(namespace)。如果发生故障转移,备用服务器在将自己提升为活动状态之前,它会已从JounalNodes中读取所有编辑。这确保了在故障转移发生之前命名空间状态已完全同步。

为了实现快速故障切换,备用节点还需要集群中块的位置的最新信息。为了实现这一点,DataNode配置了两个NameNode的位置,并将块位置信息和心跳发送到两者。

HA群集的正确操作对于一次只有一个NameNode处于活动状态至关重要。否则,命名空间状态将很快在两者之间发生分歧,从而可能导致数据丢失或其他不正确的结果。为了确保这个属性并防止所谓的“裂脑场景”(split-brain scenario),JournalNodes一次只允许一个NameNode进行写入。在故障转移期间,要成为活动状态的NameNode,只需要简单地接管写入JournalNodes的角色,这将有效地防止其他NameNode继续处于活动状态,从而允许新的活动节点,进行安全地进行故障转移。

4、硬件资源

为了部署HA群集,您应该准备以下内容:

  • NameNode机器 - 运行Active和Standby NameNode的机器应该具有相同的硬件。

  • JournalNode机器 - JournalNode守护进程相对轻量级,因此这些守护进程可以合理地与具有其他Hadoop守护进程并行,例如NameNodes,JobTracker或YARN ResourceManager。注意:必须至少有3个JournalNode守护进程,因为必须将编辑日志修改写入大多数JN。这样做,将允许系统容忍单台机器的故障。您也可以运行3个以上的JournalNodes,但为了增加系统可以容忍的失败次数,您应该运行奇数个JN(即3,5,7等)。请注意,在运行N个JournalNodes时,系统最多可以承受(N-1)/2 个JN节点故障并继续正常运行。

请注意,在HA群集中,备用NameNode还会执行名称空间状态的检查点操作,因此不需要在HA群集中运行Secondary NameNode,CheckpointNode或BackupNode。事实上,这样也是错误的错误。它允许在未启用HA的HDFS群集上,重新使用之前专用于Secondary NameNode的主机上启用HA。

4、部署

配置概要

与联邦配置类似,HA配置是向后兼容的,并允许现有的单NameNode的配置成HA,而不改变其当前的工作状态。与 新配置的设计使集群中的所有节点都可以具有相同的配置,而无需根据节点的类型将不同的配置文件部署到不同的机器。

和HDFS配置一样,HA集群重用名称服务ID(nameservice ID)来标识实际上可能由多个HA NameNode组成的单个HDFS实例。 另外,HA中添加了名为NameNode ID的新抽象。 群集中每个不同的NameNode都有一个不同的NameNode ID来区分它。 为了支持所有NameNode的单个配置文件,相关配置参数后缀名称服务ID以及NameNode ID。

配置详情

要配置HA NameNode,您必须将多个配置选项添加到您的hdfs-site.xml配置文件。

您设置这些配置的顺序并不重要,但是您为dfs.nameservices和dfs.ha.namenodes。[nameservice ID]选择的值将决定后面的那些键。 因此,您应该在设置其余配置选项之前决定这些值。

  • dfs.nameservices - 这个nameservice新的逻辑名称

为此名称服务选择一个逻辑名称,例如“mycluster”,并使用此逻辑名称作为此配置选项的值。名字可以是任意的字符。 它将用于其他配置及组件的绝对路径。

注意:如果您还使用HDFS联合身份验证,则此配置设置还应该包含其他名称服务(HA或其他)的列表,以逗号分隔列表。

<property>
  <name>dfs.nameservices</name>
  <value>mycluster</value>
</property>
  • dfs.ha.namenodes[nameservice ID] - 名称服务中每个NameNode的唯一标识符

配置一个由逗号分隔的NameNode ID列表。 这将由DataNode用于确定群集中的所有NameNode。 例如,如果您以前使用“mycluster”作为名称服务标识,并且您希望使用“nn1”和“nn2”作为NameNodes的单个标识,则可以这样配置它:

<property>
  <name>dfs.ha.namenodes.mycluster</name>
  <value>nn1,nn2</value>
</property>

注意:目前,每个名称服务最多只能配置两个NameNode。

  • dfs.namenode.rpc-address.[nameservice ID].[name node ID] - 每个NameNode监听的RPC地址

对于之前配置的NameNode ID,请设置NameNode进程的完整地址和IPC端口。请注意,这会导致两个单独的配置选项。例如:

<property>
  <name>dfs.namenode.rpc-address.mycluster.nn1</name>
  <value>machine1.example.com:8020</value>
</property>
<property>
  <name>dfs.namenode.rpc-address.mycluster.nn2</name>
  <value>machine2.example.com:8020</value>
</property>

注意:如果您愿意,您可以类似地配置“servicerpc-address”设置。

  • dfs.namenode.http-address.[nameservice ID].[name node ID] - 每个NameNode监听的完全限定的HTTP地址。

与上面的rpc-address类似,为两个NameNode的HTTP服务器设置侦听地址。例如:

<property>
  <name>dfs.namenode.http-address.mycluster.nn1</name>
  <value>machine1.example.com:50070</value>
</property>
<property>
  <name>dfs.namenode.http-address.mycluster.nn2</name>
  <value>machine2.example.com:50070</value>
</property>

注意:如果您启用了Hadoop的安全功能,则还应该为每个NameNode设置类似的https地址。

  • dfs.namenode.shared.edits.dir - 标识NameNode将写入/读取编辑的JN组的URI

这是配置提供共享编辑存储的JournalNode的地址的地址,由Active NameNode写入并由Standby NameNode读取,以保持Active NameNode所做的所有文件系统更改的最新状态。 尽管您必须指定多个JournalNode地址,但您应该只配置其中一个URI。 URI的格式应为:`qjournal://*host1:port1*;*host2:port2*;*host3:port3*/*journalId*。 日志ID是此名称服务的唯一标识符,它允许一组JournalNodes为多个联邦名称系统提供存储。 虽然不是必需的,但重用日志标识符的名称服务ID是个不错的选择。

例如,如果此群集的JournalNodes在计算机“node1.example.com”,“node2.example.com”和“node3.example.com”上运行并且名称服务ID是“mycluster”,则可以使用 以下作为此设置的值(JournalNode的默认端口为8485):

<property>
  <name>dfs.namenode.shared.edits.dir</name>
  <value>qjournal://node1.example.com:8485;node2.example.com:8485;node3.example.com:8485/mycluster</value>
</property>
  • dfs.client.failover.proxy.provider.[nameservice ID] - HDFS客户端用于联系Active NameNode的Java类

配置将由DFS客户端使用的Java类的名称,以确定哪个NameNode是当前的Active,以及哪个NameNode当前正在为客户端请求提供服务。 目前Hadoop附带的两个实现是ConfiguredFailoverProxyProvider和RequestHedgingProxyProvider(对于第一个调用,它同时调用所有名称节点来确定活动的名称节点,并且在随后的请求中调用活动的名称节点直到发生故障转移),所以 除非您使用自定义代理提供程序,否则请使用其中之一。 例如:

<property>
  <name>dfs.client.failover.proxy.provider.mycluster</name>
  <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
  • dfs.ha.fencing.methods - 一个脚本或Java类的列表,这些脚本或Java类将用于在故障转移期间杀死活动NameNode。

系统的正确性是可取的,即在任何给定时间只有一个NameNode处于活动状态。重要的是,在使Quorum Journal Manager时,只有一个NameNode将被允许写入JournalNodes,因此不会破坏裂脑场景中的文件系统元数据。但是,当发生故障转移时,前一个活动NameNode仍可能向客户端提供读取请求,这可能会过时,直到NameNode在尝试写入JournalNodes时关闭。因此,即使在使用Quorum Journal Manager时,仍需要配置一些防护方法。但是,为了在防护机制发生故障的情况下提高系统的可用性,建议配置一种防护方法,该防护方法可保证作为列表中的最后一个防护方法返回成功。请注意,如果您选择不使用实际的防护方法,则仍必须为此设置配置一些内容,例如“shell(/bin/true)”。

故障切换期间使用的防护方法将配置为一个以回车分隔的列表,该列表将按顺序尝试,直到指示防护成功为止。 Hadoop提供了两种方法:shell和sshfence。 有关实现自己的自定义fencing方法的信息,请参阅org.apache.hadoop.ha.NodeFencer类。

sshfence - SSH到活动NameNode并杀死进程

sshfence选项通过SSH连接到目标节点并使用fuser来终止侦听服务的TCP端口的进程。 为了使此隔离选项正常工作,它必须能够在不提供密码的情况下通过SSH连接到目标节点。 因此,还必须配置dfs.ha.fencing.ssh.private-key-files选项,该选项是SSH私钥文件的以逗号分隔的列表。 例如:

<property>
  <name>dfs.ha.fencing.methods</name>
  <value>sshfence</value>
</property>

<property>
  <name>dfs.ha.fencing.ssh.private-key-files</name>
  <value>/home/exampleuser/.ssh/id_rsa</value>
</property>

或者,可以配置非标准用户名或端口来执行SSH。也可以为SSH配置超时(以毫秒为单位),此后,此隔离方法将被视为失败。它可以像这样配置:

<property>
  <name>dfs.ha.fencing.methods</name>
  <value>sshfence([[username][:port]])</value>
</property>
<property>
  <name>dfs.ha.fencing.ssh.connect-timeout</name>
  <value>30000</value>
</property>

shell - 运行一个任意的shell命令来隔离活动NameNode

shell fencing方法运行任意shell命令。它可以像这样配置:

<property>
  <name>dfs.ha.fencing.methods</name>
  <value>shell(/path/to/my/script.sh arg1 arg2 ...)</value>
</property>

‘(’ and ‘)’ 之间的字符串直接传递给bash shell,可能不包含任何右括号。

shell命令将在设置为包含所有当前Hadoop配置变量的环境下运行,’_‘字符替换配置键中的任何’.’字符。 所使用的配置已将任何名称特定于节点的配置升级为其通用形式 - 例如dfs_namenode_rpc-address将包含目标节点的RPC地址,即使配置可能将该变量指定为dfs.namenode.rpc-address.ns1.nn1

此外,还提供了以下指向要防护的目标节点的变量:

命名选项 描述
$target_host 要被隔离的节点的主机名
$target_port 节点的IPC端口
$target_address 以上两个,合并为主机:端口
$target_nameserviceid 要防护的NN的名称服务ID
$target_namenodeid 要防护的NN的namenode ID

这些环境变量也可以用作shell命令本身的替换。例如:

<property>
  <name>dfs.ha.fencing.methods</name>
  <value>shell(/path/to/my/script.sh --nameservice=$target_nameserviceid $target_host:$target_port)</value>
</property>

如果shell命令返回退出码0,则确定防护成功。如果它返回任何其他退出代码,则防护未成功,并尝试列表中的下一个防护方法。

注意:此防护方法不会实现任何超时。如果超时是必要的,它们应该在shell脚本中实现(例如通过派生一个子shell在几秒钟内杀死它的父代)

  • fs.defaultFS - 当没有给出Hadoop FS客户端使用的默认路径前缀

或者,您现在可以将Hadoop客户端的默认路径配置为使用新的启用HA的逻辑URI。 如果您之前使用“mycluster”作为名称服务标识,则这将是所有HDFS路径的权限部分的值。 这可能是这样配置的,在你的core-site.xml文件中:

<property>
  <name>fs.defaultFS</name>
  <value>hdfs://mycluster</value>
</property>
  • dfs.journalnode.edits.dir - JournalNode守护进程将存储其本地状态的路径

这是JournalNode计算机上绝对路径,JN将使用编辑和其他本地状态进行存储。 您只能为此配置使用单个路径。 通过运行多个单独的JournalNode或通过在本地连接的RAID阵列上配置此目录来提供此数据的冗余。 例如:

<property>
  <name>dfs.journalnode.edits.dir</name>
  <value>/path/to/journal/node/local/data</value>
</property>

5、部署细节

在设置了所有必要的配置选项之后,您必须在它们将运行的机器集上启动JournalNode守护进程。 这可以通过运行命令hadoop-daemon.sh start journalnode并等待守护进程在每台相关机器上启动来完成。

JournalNodes启动后,必须首先同步两个HA NameNodes的磁盘元数据。

  • 如果您正在设置新的HDFS集群,则应首先在NameNode之一上运行format命令(hdfs namenode -format)。

  • 如果您已经格式化NameNode,或正在将未启用HA的群集转换为启用HA,则现在应该通过运行命令hdfs namenode -bootstrapStandby - 将您的NameNode元数据目录的内容复制到另一个未格式化的NameNode, bootstrapStandby“放在未格式化的NameNode上。 运行此命令还将确保JournalNodes(由dfs.namenode.shared.edits.dir配置)包含足够的编辑事务,以便能够启动两个NameNode。

  • 如果要将非HA NameNode转换为HA,则应运行命令hdfs namenode -initializeSharedEdits,该命令将使用来自本地NameNode编辑目录的编辑数据初始化JournalNodes。

此时,您可以像启动NameNode一样启动两个HA NameNode。

您可以通过浏览到其配置的HTTP地址来分别访问每个NameNode的网页。 您应该注意到,配置的地址旁边将是NameNode的HA状态(“standby”或“active”)。每当HA NameNode启动时,它最初都处于Standby状态。

管理命令

现在您的HA NameNode已配置并启动,您将可以访问一些其他命令来管理HA HDFS集群。 具体来说,您应该熟悉“hdfs haadmin”命令的所有子命令。 不带任何附加参数运行此命令将显示以下使用信息:

Usage: haadmin
    [-transitionToActive <serviceId>]
    [-transitionToStandby <serviceId>]
    [-failover [--forcefence] [--forceactive] <serviceId> <serviceId>]
    [-getServiceState <serviceId>]
    [-getAllServiceState]
    [-checkHealth <serviceId>]
    [-help <command>]

本指南介绍了每个子命令的高级用法。有关每个子命令的具体使用信息,应运行“hdfs haadmin -help <命令>”

  • transitionToActive and transitionToStandby - 给定NameNode的状态转换为Active或Standby

这些子命令会使给定的NameNode分别转换到活动或待机状态。 这些命令不会尝试执行任何防护,因此应该很少使用。 相反,人们应该总是喜欢使用“hdfs haadmin -failover”子命令。

  • failover - 在两个NameNode之间启动故障转移

此子命令导致从第一个提供的NameNode到第二个的故障转移。 如果第一个NameNode处于Standby状态,则此命令只是将第二个NameNode转换为Active状态而不会出错。 如果第一个NameNode处于Active状态,则会尝试将其正常转换到Standby状态。 如果失败,则会尝试按照顺序尝试防护方法(由dfs.ha.fencing.methods配置),直到成功为止。 只有在这个过程之后,第二个NameNode才会转换到活动状态。 如果没有防护方法成功,则第二个NameNode不会转换为活动状态,并且会返回错误。

  • getServiceState - 确定给定的NameNode是Active还是Standby

连接到已配置的NameNode以确定当前状态,适当地向STDOUT打印“Standby”或“Active”。此子命令可能由cron作业或监视脚本使用,这些脚本需要根据NameNode当前处于活动状态还是待机状态而具有不同的行为。

  • getAllServiceState - 返回所有NameNode的状态

连接到已配置的NameNode以确定当前状态,适当地向STDOUT打印“Standby”或“Active”。

  • checkHealth - 检查给定NameNode的健康状况

连接到提供的NameNode以检查其健康状况。 NameNode能够对自身执行一些诊断,包括检查内部服务是否按预期运行。 如果NameNode健康,该命令将返回0,否则返回非零值。 有人可能会将此命令用于监视目的。

注意:这个功能还没有完全实现,并且目前将始终返回成功,除非给定的NameNode完全关闭。

6、故障自动切换

简介

以上各节介绍如何配置手动故障转移。 在该模式下,即使主动节点发生故障,系统也不会自动触发从活动节点到备用节点的故障转移。 本节介绍如何配置和部署自动故障转移。

组件

自动故障转移为HDFS部署添加了两个新组件:一个 ZooKeeper quorum和ZKFailoverController进程(缩写为ZKFC)。

Apache ZooKeeper是一种高度可用的服务,用于维护少量协调数据,通知客户端数据发生变化,并监视客户端的故障。 自动HDFS故障转移的实现依赖ZooKeeper进行以下操作:

  • 故障检测 - 群集中的每个NameNode机器都在ZooKeeper中维护一个持久会话。如果机器崩溃,ZooKeeper会话将过期,并通知其他NameNode应该触发故障转移。

  • 活动NameNode选举 - ZooKeeper提供了一种简单的机制来独占一个活跃的节点。如果当前活动的NameNode崩溃,另一个节点可能会在ZooKeeper中使用一个特殊的独占锁,表明它应该成为下一个活动的Namenode.

ZKFailoverController(ZKFC)是一个新的组件,它是一个ZooKeeper客户端,它也监视和管理NameNode的状态。运行NameNode的每台机器也运行一个ZKFC,并由ZKFC负责:

  • 健康监测 - ZKFC通过健康检查命令定期对其本地NameNode进行ping。 只要NameNode及时响应并具有健康状态,ZKFC就认为节点健康。 如果节点崩溃,冻结或以其他方式进入不健康状态,则健康监视器会将其标记为不健康。

  • ZooKeeper会话管理 - 当本地NameNode健康时,ZKFC将在ZooKeeper中打开一个会话。 如果本地NameNode处于活动状态,则它还包含一个特殊的“锁定”znode。 该锁使用ZooKeeper对“短暂”节点的支持; 如果会话过期,锁定节点将被自动删除。

  • 基于ZooKeeper的选举 - 如果本地NameNode健康,并且ZKFC发现其他节点当前没有锁znode,它将自己尝试获取该锁。 如果成功,则它“赢得选举”,并负责运行故障转移以使其本地NameNode处于活动状态。 故障转移过程与上述手动故障转移类似:首先,如果必要,先前的活动会被屏蔽,然后本地NameNode转换为活动状态。

有关自动故障转移设计的更多详细信息,请参阅Apache HDFS JIRA上HDFS-2185附带的设计文档。

部署ZooKeeper

在典型的部署中,ZooKeeper守护进程被配置为在三个或五个节点上运行。 由于ZooKeeper本身具有轻量资源需求,因此可以在与HDFS NameNode和Standby节点相同的硬件上配置ZooKeeper节点。 许多运营商选择在与YARN ResourceManager相同的节点上部署第三个ZooKeeper进程。 建议将ZooKeeper节点配置为将其数据存储在HDFS元数据的单独磁盘驱动器上,以获得最佳性能和隔离。

ZooKeeper的设置不在本文档的范围内。我们将假设您已经建立了一个运行在三个或更多节点上的ZooKeeper集群,并通过使用ZK CLI进行连接来验证其正确的操作。

运行之前

在开始配置自动故障转移之前,您应该关闭群集。当集群正在运行时,目前无法从手动故障转移设置转换为自动故障转移设置。

配置自动故障转移

自动故障转移的配置需要在配置中添加两个新参数。在您的hdfs-site.xml文件中,添加:

 <property>
   <name>dfs.ha.automatic-failover.enabled</name>
   <value>true</value>
 </property>

指定应将群集设置为自动故障转移。在你的core-site.xml文件中,添加:

 <property>
   <name>ha.zookeeper.quorum</name>
   <value>zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181</value>
 </property>

以上配置列出了运行ZooKeeper服务的主机端口对。

与文档中前面介绍的参数一样,可以通过在名称服务的基础上配置名称服务ID后缀来配置这些设置。 例如,在启用了联邦群集中,您可以通过设置dfs.ha.automatic-failover.enabled.my-nameservice-id为其中一个名称服务显式启用自动故障转移。

还可以设置其他几个配置参数来控制自动故障转移的行为;然而,对于大多数安装来说,它们并不是必需的,有关详细信息,请参阅配置密钥特定文档。

ZooKeeper中初始化HA状态

添加配置密钥后,下一步是在ZooKeeper中初始化所需的状态。您可以通过从其中一个NameNode主机运行以下命令来完成此操作。

[hdfs]$ $HADOOP_PREFIX/bin/hdfs zkfc -formatZK

这将在自动故障转移系统存储其数据的ZooKeeper中创建一个znode。

使用start-dfs.sh启动集群

由于配置中启用了自动故障转移功能,因此start-dfs.sh脚本将自动在任何运行NameNode的计算机上启动ZKFC守护程序。 当ZKFC启动时,他们将自动选择其中一个NameNode变为活动状态。

手动启动集群

如果您手动管理群集上的服务,则需要在运行NameNode的每台机器上手动启动zkfc守护进程。您可以运行以下命令来启动守护进程:

[hdfs]$ $HADOOP_PREFIX/sbin/hadoop-daemon.sh --script $HADOOP_PREFIX/bin/hdfs start zkfc

安全访问ZooKeeper

如果您正在运行的集群有安全方面的要求,您可能需要确保存储在ZooKeeper中的信息也是安全的。这可以防止恶意客户修改ZooKeeper中的元数据或者可能触发错误的故障转移。

为了保护ZooKeeper中的信息,首先将以下内容添加到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 CLI使用的相同格式的ZooKeeper认证列表。例如,您可以指定如下所示的内容:

digest:hdfs-zkfcs:mypassword

…其中hdfs-zkfcs是ZooKeeper的唯一用户名,mypassword是一些用作密码的唯一字符串。

接下来,使用类似下面的命令生成与此验证对应的ZooKeeper 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命令,如上所述。 这样做后,您可以按如下方式验证ZK CLI的ACL:

[zk: localhost:2181(CONNECTED) 1] getAcl /hadoop-ha
'digest,'hdfs-zkfcs:vlUvLnd8MlacsE80rDuu6ONESbM=
: cdrwa

验证故障自动转移

设置好了自动故障转移后,有必要对其进行测试。为此,首先找到活动的NameNode。您可以通过访问NameNode Web界面来确定哪个节点处于活动状态 - 每个节点都会在页面顶部报告其HA状态。

找到活动的NameNode后,你可以模拟失败。 例如,可以使用kill -9 <NN>的pid来模拟JVM崩溃。 或者,您可以重新启动机器或拔下其网络接口以模拟其他类型的中断。 触发您希望测试的中断后,另一个NameNode应在几秒钟内自动激活。 检测故障并触发故障切换所需的时间取决于ha.zookeeper.session-timeout.ms的配置,但默认为5秒。

如果测试不成功,则可能是配置错误。检查zkfc守护进程以及NameNode守护进程的日志,以便进一步诊断问题。

自动故障转移常见问题

  • 启动ZKFC和NameNode守护进程的顺序是否很重要?

不重要。在任何给定节点上,您可以在其相应的NameNode之前或之后启动ZKFC。

我应该进行哪些额外的监测?

您应该在运行NameNode的每台主机上添加监控,以确保ZKFC保持运行。 例如,在某些类型的ZooKeeper故障中,ZKFC可能意外退出,应该重新启动以确保系统已准备好进行自动故障转移。

此外,您应该监视ZooKeeper quorum的每个服务器。如果ZooKeeper崩溃,则自动故障转移将不起作用。

  • 如果ZooKeeper出现故障会发生什么?

如果ZooKeeper群集崩溃,则不会触发自动故障转移。但是,HDFS将继续运行,没有任何影响。当ZooKeeper重新启动时,HDFS将不会自动重新连接。

  • 我可以将我的NameNode中的一个指定为主/首选吗?

目前不支持。 NameNode首先启动的任何一个都将变为活动状态。您可以选择以特定顺序启动群集,以便首选节点首先启动。

  • 如何在配置自动故障转移时启动手动故障转移?

即使配置了自动故障切换,也可以使用相同的hdfs haadmin命令启动手动故障切换。它将协调故障转移。

已启用HA的HDFS Upgrade/Finalization/Rollback

在HDFS版本之间移动时,有时可以简单地安装新软件并重新启动集群。 然而,有时候,升级正在运行的HDFS版本可能需要更改磁盘上的数据。 在这种情况下,安装新软件后必须使用HDFS Upgrade/Finalization/Rollback 功能。 在高可用性环境中,这个过程变得更加复杂,因为NN依赖的磁盘上元数据按照定义分布在对中的两个HA NN上,并且在QJM用于 共享编辑存储。 本文档部分描述在HA设置中使用HDFS Upgrade/Finalization/Rollback 功能的过程。

要执行HA升级,必须执行以下操作:

1、正常关闭所有NN,然后安装较新的软件

2、启动所有的JN。请注意,在执行升级,回滚或最终化操作时,所有JN都需要运行。如果任何JN在运行这些操作时都处于关闭状态,则操作将失败。

3、用’-upgrade’标志启动一个NN。

4、在开始时,这个NN不会像往常一样在HA设置中进入待机状态。相反,此NN将立即进入活动状态,执行其本地存储目录的升级,并且还执行共享编辑日志的升级。

5、此时,HA对中的其他NN将与升级的NN不同步。 为了使其恢复同步并且再次具有高度可用的设置,您应该通过使用’-bootstrapStandby’标志运行NN来重新引导此NameNode。 用’-upgrade’标志启动第二个NN是错误的。

请注意,如果在任何时候想要在完成或回滚升级之前重新启动NameNodes,则应该照常启动NN,即不需要任何特殊的启动标志。

结束高可用性升级,使用hdfs dfsadmin -finalizeUpgrade命令,并且NN其中一个处于活动状态。 在这种情况下,活动NN将终止操作共享日志,而本地存储目录包含前一个FS状态的NN,本地当前的状态将会被删除。

要执行升级的回滚,应首先关闭两个NN。 在NN发起升级程序的NN上运行回滚命令,该命令将在那里执行本地dir的回滚以及共享日志(NFS或JN)上的回滚。 之后,应该启动这个NN,并且应该在另一个NN上运行-bootstrapStandby,以使这两个NN与这个回滚的文件系统状态同步。