目的(Purpose)

使用仲裁日志管理器(QJM)功能概述了HDFS高可用性(HA)功能以及如何配置和管理HA HDFS群集。

背景(Background)

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

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

1)在计划外事件(例如机器崩溃)的情况下,直到操作员重新启动NameNode后,集群才可用。

2)计划的维护事件(如NameNode计算机上的软件或硬件升级)将导致集群停机。

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

体系结构(Architecture)

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

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

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

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

硬件资源(Hardware resources

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

1)NameNode计算机 - 运行Active和Standby NameNode的计算机应该具有彼此相同的硬件,以及与非HA集群中使用的硬件相同的硬件。

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

请注意,在HA群集中,备用NameNode还执行名称空间状态的检查点,因此不需要在HA群集中运行Secondary NameNode,CheckpointNode或BackupNode。事实上,这样做会是一个错误。

部署(Deployment)

配置概述(Configuration overview)

HA配置向后兼容,并允许现有的单一NameNode配置无需更改即可运行。新配置的设计使集群中的所有节点都可以具有相同的配置,而无需根据节点的类型将不同的配置文件部署到不同的机器。

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

配置细节(Configuration details)

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

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

配置属性

描述

示例

dfs.nameservices

dfs.nameservices - the logical name for this new nameservice

Choose a logical name for this nameservice, for example "mycluster", and use this logical name for the value of this config option. The name you choose is arbitrary. It will be used both for configuration and as the authority component of absolute HDFS paths in the cluster.

Note: If you are also using HDFS Federation, this configuration setting should also include the list of other nameservices, HA or otherwise, as a comma-separated list.

dfs.nameservices - 这个新名称服务的逻辑名称

为此名称服务选择一个逻辑名称,例如“mycluster”,并使用此逻辑名称作为此配置选项的值。你选择的名字是任意的。它将用于配置,也可用作群集中绝对HDFS路径的权威组件。

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

  dfs.nameservices

  mycluster

dfs.ha.namenodes.[nameservice ID]

dfs.ha.namenodes.[nameservice ID] - unique identifiers for each NameNode in the nameservice

Configure with a list of comma-separated NameNode IDs. This will be used by DataNodes to determine all the NameNodes in the cluster. For example, if you used "mycluster" as the nameservice ID previously, and you wanted to use "nn1" and "nn2" as the individual IDs of the NameNodes, you would configure this。

Note: Currently, only a maximum of two NameNodes may be configured per nameservice.

名称服务中每个NameNode的唯一标识符

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

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

  dfs.ha.namenodes.mycluster

  nn1,nn2

dfs.namenode.rpc-address.[nameservice ID].[name node ID]

dfs.namenode.rpc-address.[nameservice ID].[name node ID] - the fully-qualified RPC address for each NameNode to listen on

For both of the previously-configured NameNode IDs, set the full address and IPC port of the NameNode processs. Note that this results in two separate configuration options. 

Note: You may similarly configure the "servicerpc-address" setting if you so desire.

每个NameNode监听的完全限定的RPC地址

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

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

  dfs.namenode.rpc-address.mycluster.nn1

  machine1.example.com:8020

  dfs.namenode.rpc-address.mycluster.nn2

  machine2.example.com:8020

dfs.namenode.http-address.[nameservice ID].[name node ID]

dfs.namenode.http-address.[nameservice ID].[name node ID] - the fully-qualified HTTP address for each NameNode to listen on

Similarly to rpc-address above, set the addresses for both NameNodes' HTTP servers to listen on. 

Note: If you have Hadoop's security features enabled, you should also set the https-address similarly for each NameNode.

每个NameNode监听的完全限定的HTTP地址

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

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

  dfs.namenode.http-address.mycluster.nn1

  machine1.example.com:50070

  dfs.namenode.http-address.mycluster.nn2

  machine2.example.com:50070

dfs.namenode.shared.edits.dir

dfs.namenode.shared.edits.dir - the URI which identifies the group of JNs where the NameNodes will write/read edits

This is where one configures the addresses of the JournalNodes which provide the shared edits storage, written to by the Active nameNode and read by the Standby NameNode to stay up-to-date with all the file system changes the Active NameNode makes. Though you must specify several JournalNode addresses, you should only configure one of these URIs. The URI should be of the form: "qjournal://host1:port1;host2:port2;host3:port3/journalId". The Journal ID is a unique identifier for this nameservice, which allows a single set of JournalNodes to provide storage for multiple federated namesystems. Though not a requirement, it's a good idea to reuse the nameservice ID for the journal identifier.

For example, if the JournalNodes for this cluster were running on the machines "node1.example.com", "node2.example.com", and "node3.example.com" and the nameservice ID were "mycluster", you would use the following as the value for this setting (the default port for the JournalNode is 8485):

标识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):

  dfs.namenode.shared.edits.dir

  qjournal://node1.example.com:8485;node2.example.com:8485;node3.example.com:8485/mycluster

dfs.client.failover.proxy.provider.[nameservice ID]

dfs.client.failover.proxy.provider.[nameservice ID] - the Java class that HDFS clients use to contact the Active NameNode

Configure the name of the Java class which will be used by the DFS Client to determine which NameNode is the current Active, and therefore which NameNode is currently serving client requests. The only implementation which currently ships with Hadoop is the ConfiguredFailoverProxyProvider, so use this unless you are using a custom one. For example:

HDFS客户端用于联系Active NameNode的Java类

配置将由DFS客户端使用的Java类的名称,以确定哪个NameNode是当前的Active,以及哪个NameNode当前正在为客户端请求提供服务。目前与Hadoop一起提供的唯一实现是ConfiguredFailoverProxyProvider,因此除非您使用自定义配置,否则请使用它。

  dfs.client.failover.proxy.provider.mycluster

  org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider

dfs.ha.fencing.methods

dfs.ha.fencing.methods - It is desirable for correctness of the system that only one NameNode be in the Active state at any given time. Importantly, when using the Quorum Journal Manager, only one NameNode will ever be allowed to write to the JournalNodes, so there is no potential for corrupting the file system metadata from a split-brain scenario. However, when a failover occurs, it is still possible that the previous Active NameNode could serve read requests to clients, which may be out of date until that NameNode shuts down when trying to write to the JournalNodes. For this reason, it is still desirable to configure some fencing methods even when using the Quorum Journal Manager. However, to improve the availability of the system in the event the fencing mechanisms fail, it is advisable to configure a fencing method which is guaranteed to return success as the last fencing method in the list. Note that if you choose to use no actual fencing methods, you still must configure something for this setting, for example "shell(/bin/true)".

The fencing methods used during a failover are configured as a carriage-return-separated list, which will be attempted in order until one indicates that fencing has succeeded. There are two methods which ship with Hadoop: shell and sshfence. For information on implementing your own custom fencing method, see the org.apache.hadoop.ha.NodeFencer class.

在故障转移期间将用于遏制活动NameNode的脚本或Java类的列表

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

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

sshfence - SSH to the Active NameNode and kill the process

The sshfence option SSHes to the target node and uses fuser to kill the process listening on the service's TCP port. In order for this fencing option to work, it must be able to SSH to the target node without providing a passphrase. Thus, one must also configure the dfs.ha.fencing.ssh.private-key-files option, which is a comma-separated list of SSH private key files. For example:

  dfs.ha.fencing.methods

  sshfence

  dfs.ha.fencing.ssh.private-key-files

  /home/exampleuser/.ssh/id_rsa

SSH到活动NameNode并杀死进程

该sshfence选项SSHes到目标节点,并杀死进程。为了使此隔离选项正常工作,它必须能够在不提供密码的情况下通过SSH连接到目标节点。因此,还必须配置dfs.ha.fencing.ssh.private-key-files选项

Optionally, one may configure a non-standard username or port to perform the SSH. One may also configure a timeout, in milliseconds, for the SSH, after which this fencing method will be considered to have failed. It may be configured like so:

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

  dfs.ha.fencing.methods

  sshfence([[username][:port]])

  dfs.ha.fencing.ssh.connect-timeout

  30000

shell - run an arbitrary shell command to fence the Active NameNode

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

  dfs.ha.fencing.methods

  shell(/path/to/my/script.sh arg1 arg2 ...)

或者

  dfs.ha.fencing.methods

  shell(/path/to/my/script.sh --nameservice=$target_nameserviceid $target_host:$target_port)

If the shell command returns an exit code of 0, the fencing is determined to be successful. If it returns any other exit code, the fencing was not successful and the next fencing method in the list will be attempted.

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

fs.defaultFS

fs.defaultFS - the default path prefix used by the Hadoop FS client when none is given

Optionally, you may now configure the default path for Hadoop clients to use the new HA-enabled logical URI. If you used "mycluster" as the nameservice ID earlier, this will be the value of the authority portion of all of your HDFS paths. This may be configured like so, in your core-site.xml file:

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

  fs.defaultFS

  hdfs://mycluster

dfs.journalnode.edits.dir

dfs.journalnode.edits.dir - the path where the JournalNode daemon will store its local state

This is the absolute path on the JournalNode machines where the edits and other local state used by the JNs will be stored. You may only use a single path for this configuration. Redundancy for this data is provided by running multiple separate JournalNodes, or by configuring this directory on a locally-attached RAID array. 

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

  dfs.journalnode.edits.dir

  /path/to/journal/node/local/data

NFS实现HA配置文件的区别:

注释hdfs-site.xml这两配置

  

  dfs.namenode.shared.edits.dir  

  qjournal://node2:8485;node3:8485;node4:8485/jiaozi  

  

  

  dfs.journalnode.edits.dir  

  /journaldata  

添加nfs读取共享目录

  

  dfs.namenode.shared.edits.dir  

  file:///mnt/  

  

其他配置一样

部署详情(Deployment details)

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

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

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

2)If you have already formatted the NameNode, or are converting a non-HA-enabled cluster to be HA-enabled, you should now copy over the contents of your NameNode metadata directories to the other, unformatted NameNode by running the command "hdfs namenode -bootstrapStandby" on the unformatted NameNode. Running this command will also ensure that the JournalNodes (as configured by dfs.namenode.shared.edits.dir) contain sufficient edits transactions to be able to start both NameNodes.

如果你已经格式化NameNode,或者将非HA启用的集群转换为启用HA,应该现在把NameNode的元数据目录中的内容复制到其它,未格式化的NameNode运行“hdfs namenode -bootstrapStandby”命令。运行这个命令还将确保JournalNodes(由dfs.namenode.shared.edits.dir配置)包含足够的编辑事务,以便能够启动两个NameNode。

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

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

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

管理命令(Administrative commands)

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

Usage: DFSHAAdmin [-ns ]

    [-transitionToActive ]

    [-transitionToStandby ]

    [-failover [--forcefence] [--forceactive] ]

    [-getServiceState ]

    [-checkHealth ]

    [-help ]

下面介绍了每个子命令的高级用法。有关每个子命令的具体使用信息,应运行“ 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以确定其当前状态,适当地打印“standby”或“active”到STDOUT。此子命令可能由cron作业或监视脚本使用,这些脚本需要根据NameNode当前处于活动状态还是待机状态而具有不同的行为。

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

连接到提供的NameNode以检查其健康状况。NameNode能够对自身执行一些诊断,包括检查内部服务是否按预期运行。如果NameNode健康,该命令将返回0,否则返回非零值。有人可能会将此命令用于监视目的。注意:这还没有实现,并且目前将始终返回成功,除非给定的NameNode完全关闭。

自动故障转移(Automatic Failover)

介绍(Introduction)

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

组件(Components)

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

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

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

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

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

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

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

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

部署ZooKeeper(Deploying ZooKeeper

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

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

在你开始之前(Before you begin

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

配置自动故障转移(Configuring automatic failover

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

   dfs.ha.automatic-failover.enabled

   true

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

   ha.zookeeper.quorum

   zk1.example.com:2181,zk2.example.com:2181,zk3.example.com:2181

这列出了运行ZooKeeper服务的主机端口。

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

用start-dfs.sh启动集群(Starting the cluster with start-dfs.sh)

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

手动启动集群(Starting the cluster manually)

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

$ hadoop-daemon.sh start zkfc

确保访问ZooKeeper(Securing access to ZooKeeper)

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

为了保护ZooKeeper中的信息,首先将以下内容添加到core-site.xml文件中:

   ha.zookeeper.auth

   @/path/to/zk-auth.txt

   ha.zookeeper.acl

   @/path/to/zk-acl.txt

请注意这些值中的'@'字符 - 它指定配置不是内联的,而是指向磁盘上的文件。

第一个配置的文件指定了ZK CLI使用的相同格式的ZooKeeper认证列表。例如,您可以指定如下所示的内容:

digest:hdfs-zkfcs:mypassword

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

接下来,使用类似下面的命令生成与此验证对应的ZooKeeper ACL:

$ 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

验证自动故障转移(Verifying automatic failover)

一旦设置了自动故障转移,您应该测试其操作。为此,首先找到活动的NameNode。您可以通过访问NameNode Web界面来确定哪个节点处于活动状态 - 每个节点都会在页面顶部报告其HA状态。

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

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