在正式环境中,搭建高可靠(ha)的系统是必须的。

例如oralce的rac,apache集群,windows服务器集群

本文不再赘言ha的重要性。

本文主要是对 http://hadoop.apache.org/docs/r2.8.0/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html#Administrative_commands

的翻译,外加一些其它参考和个人的感悟。

---原文相当长

译注:ha-high availability 。原文说了半天,就是要求我们使用zookeeper来实现自动故障转移(切换),当然这也是绝大部分管理员所期望的。

1.目的

本指引提供关于HDFS高可靠特性的概览和如何配置管理高可靠hdfs集群(利用日志管理器特性qjm).

本文档假定读者已经理解主要的部件和节点类型。

2.注意:使用日志管理器还是传统的共享存储

本指引讨论如何使用qjm配置高可靠的HDFS集群,qjm的作用在于活动名称几点和备份名称节点之间共享编辑日志。

3.背景

在hadoop 2.0.0之前,HDFS集群中名称节点是单一故障点。每个集群只有单一的名称节点,如果机器或者进程发生故障,那么集群就不可用了,除非名称节点重启或者在新的机器上搭建。

这影响了HDFS集群的总体可用性,主要体现在两个途径:

  • 机器突然故障,直到一个操作员重启了名称节点
  • 计划中的维护,例如软件或者硬件升级(升级名称节点)会导致整个集群不可用

通过运行两个冗余的名称节点(一个活动,一个待命),可以避免以上提到的问题。这样如果其中一个有问题或者需要,就可以快速切换到备用节点(译注:standby ,待命,等待,备用)。

4.框架

在一个典型的ha集群中,有两个分开的机器被配置为名称节点。在任何时候,只有一个名称节点是活动状态(active),另外一个是等待状态(standby).活动的名称节点负责所有客端操作,而等待节点仅仅简单维护名称空间状态,以便需要的时候切换。

为了让等待状态的节点保持和活动节点的状态同步,两个节点都需要通过一组的守护程序来通讯,这个守护程序称为journalNodes(JNs-日志节点)。当活动节点发生任何的名称空间修改的时候,活动节点记录这些修改,并告知JNS。等地节点从JNS读取编辑日志,并立刻寻找编辑日志的变更信息。当等待节点看到编辑信息,它会应用到自身的名称空间。如果主节点发生故障,等待节点会确保自己已经从jns读取了所有的编辑信息,之后才会把自己设置为活动。这样确保名称空间完全同步故障前的内容。

为了提供给一个快速的故障切换,也需要等待节点具有及时的块位置信息。为了获得这个,数据节点必须配置两个名称节点的信息,并且心跳信息和快报告需要发送给两个节点。

一个时刻只能有一个名称节点是活动的,这是ha的必须条件。否则,名称节点的状态会分散在两个节点上,就可能导致数据丢失或者其它错误的结果。为了确保这点,并防止称为脑裂的场景,jns在一个时间点,只会允许一个写入程序。活动的节点负责写信息给jns,同时这样也会主持其它名称节点变成活动状态。

5.硬件资源

为了部署一个ha集群,我们应该准备以下内容:

  1. 名称节点机器-用于运行活动名称节点和等待名称节点,它们应该具有同样的硬件。
  2. jns机器-用于运行日志管理程序(jns)。jns守护程序相对看起来比较轻量,所以可以和其它的hadoop守护程序部署在同一机器上,那些守护程序可以是名称节点,jobtracker(作业追踪器),或者yarn资源管理器。注:至少必须有3个jns守护程序,因为编辑日志必须写入到大部分jns中。这样如果其中一些设备出现问题,那么还有一些jns可以继续工作。我们也可以运行多于3个jns,但为了提升系统的容错性,我们应该运行奇数个jns(3,5,7等等)。因为这样系统至少可以提供(n-1)/2的容错次数。

需要注意的是,在一个ha集群中,等待名称节点也执行名称空间的检查点,所以就无需运行第二名称节点,检查点节点,或者备份名称节点。

译注:关于为什么jns的守护守护程序是奇数个,这个应该和名称节点写编辑日志到jns的方式有关,由于本人并没有研究代码,所以不能解释具体是什么。

6.部署

6.1配置一览

类似于联合配置,ha配置向后兼容,并允许现有的单名称节点配置可以不用修改(配置)而继续运行。

新的配置允许集群中所有的节点具有相同的配置,这样不需要根据不同的节点类型部署同的配置文件。

译注:这的确是一个很好的想法,否则部署成千上万的集群的确是非常麻烦的,现在不用担心配置搞混这种事情。

类似于HDFS Federation,ha集群会重用nameservice ID来识别单个的HDFS实例,这个实例可能包含了多个ha名称节点。此外,一个新的抽象称为NAMENODE id 加入到ha 中。每个独立的名称节点有一个不同的NAMENODE id.

为了支持单一配置文件,相关的配置参数必须把nameservice id作为后缀,同时也带上namenode id.

6.2配置明细

为了配置ha名称节点,我们必须在hdfs-site.xml中添加几个配置。

配置的顺序无关紧要,但dfs.nameservicesdfs.ha.namenodes.[nameservice ID]的值会决定接下来配置的关键信息。因此,我们必须优先考虑这个两个。

dfs.nameservices - 名称服务的逻辑名称

<property>
  <name>dfs.nameservices</name>
  <value>mycluster</value>
</property>

译注:如果启用federation,那么就可以同时启用多个集群。启用多个集群的唯一原因,就是为了便于大家共享,其次就是增加namenode的输出能力,属于典型的并排模式。

dfs.ha.namenodes.[nameservice ID] - 名称服务中唯一的名称节点标识

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

译注:上面蓝色的mycluster是通过dfs.nameservices来决定,并非固定的。其次,目前只能允许一个ha集群终有两个名称节点,将来会支持更多一些。

最后,nn1,nn2也是一个逻辑名称罢了,不是设置为机器的实际名称。

dfs.namenode.rpc-address.[nameservice ID].[name node ID] -  名称节点的全称PRC地址,名称节点通过这个侦听rpc信息

<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>

译注:必须指定端口

dfs.namenode.http-address.[nameservice ID].[name node ID] -名称节点的http地址全称,用于侦听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的安全选项,则必须配置https-address,配置类似上面的http-address.

dfs.namenode.shared.edits.dir-jns地址,名称节点写编辑日志的目标,多个以分号分隔

uri的格式必须形如:qjournal://*host1:port1*;*host2:port2*;*host3:port3*/*journalId*.

其中journalid实际就是名称服务的唯一标识符。虽然不是强制的,但把journalid设置为何nameservice id一致,是不错的主意。(译注:也许将来hdfs就不存在journalid,直接是nameservice id了)

<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>

这个地址用于活动节点写入编辑信息,等待节点读取编辑信息。虽然我们必须设定多个jns地址,但我们只能配置一个uri.

dfs.client.failover.proxy.provider.[nameservice ID] - hdfs客户端联系活动名称节点的类

这个类的作用是识别活动节点。当前hadoop提供了两个实现,分别是ConfiguredFailoverProxyProviderRequestHedgingProxyProvider (第一次调用,会同时联系多个节点来判断哪个是活动的,随后的请求会激活活动的节点,除非发生了故障切换),

请使用两者之一,除非自行定制。例如:

<property>
  <name>dfs.client.failover.proxy.provider.mycluster</name>
  <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>

译注:RequestHedgingProxyProvider 和 ConfiguredFailoverProxyProvider 有什么区别

dfs.ha.fencing.methods - 脚本或者java类的列表,用于在故障切换中隔离活动名称节点

重点,当使用仲裁日志管理器的时候,一个时间点,只能有一个活动的名称节点,只能是活动名称节点写jns,所以即使脑裂,也不会破坏系统元数据。然而,当故障切换发生的时候,仍然有可能,前面一个活动名称节点为客户端提供读请求,这样客户端获得信息就可能是过时的。因此,即使有使用仲裁日志管理器,也有必要配置一些隔离方法。为了在隔离机制失败的时候,提升系统的可靠性,仍然有必要配置那么一个隔离方法,这个方法用于保证返回成功,好像最近的隔离方法还在清单中。

注意,如果我们选择一些没有实际作用的隔离方法,我们依然需要配置这些,例如"shell(/bin/true)".

隔离方法用回车符分隔,它们会逐个被尝试,直到返回成功。hadoop提供了两个方法:shell和sshfence.

如果想实现定制的隔离方法,请看 org.apache.hadoop.ha.NodeFencer 类。

译注:这个地址可以看 http://www.programcreek.com/java-api-examples/index.php?source_dir=hadoop-master/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ha/NodeFencer.java

sshfence - ssh到活动名称节点,并kill进程

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>

此外,还可以配置连接的用户和端口,连接时限(单位毫秒, 如果超过这个连接时限没有连接到活动节点,那么表示隔离失败).

<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>

译注:这就必要要求名称节点上要有fuser这个程序。此外,hadoop目前这种做法,也许将来不会再采取了,个人认为有点low!

shell - 运行一个强制shell命令来隔离活动名称节点

配置看起来如下:

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

位于小括号内的字符串传递了bash shell的路径,并且可能不包含任何的反小括号。(译注:对于 may not include any closing parentheses 不是很理解)

shell命令必须在具有当前hadoop配置的环境变量中运行,使用下划线(_)替换配置关键信息中任意的点号(.)。使用的配置早有名称节点有关的配置-例如dfs_namenode_rpc-address包含了目标名称节点的rpc地址,当然也可能是形如dfs.namenode.rpc-address.ns1.nn1.

此外,以下变量也是可以使用的:

$target_host               hostname of the node to be fenced  --被隔离名称节点的主机名称
$target_port               IPC port of the node to be fenced     --被隔离节点的ipc端口
$target_address          the above two, combined as host:port    --以上两个变量的合并
$target_nameserviceid  the nameservice ID of the NN to be fenced    --被隔离节点的名称服务ID
$target_namenodeid    the namenode ID of the NN to be fenced       --被隔离节点的名称节点ID

这些变量,可以直接在参数中使用,例如:

<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脚本中实现。

fs.defaultFS -  如果客户没有提供路径前缀,那么使用这个默认的

我们可以为hadoop客户端配置默认的路径,以便可以使用启用了ha的逻辑uri.

如果早先使用"mycluster"作为名称服务ID,那么这个id就是所有HDFS路径的重要部分。

我们可以在core-site.xml文件中,如下配置:

<property>
  <name>fs.defaultFS</name>
  <value>hdfs://mycluster</value>
</property>

译注: 以后访问ha的hdfs就需要带上 hdfs://mycluster之类的前缀(不需要使用hdfs://host:port之类的)

如果启用viewfs,则这个可能又不同了。

dfs.journalnode.edits.dir - jns守护程序本地用于存储编辑日志等的路径

这是一个绝对路径,位于jns机器上,用于存储编辑日志和其它本地状态。我们可能只使用一个路径。如果要路径冗余,那就需要运行多个jns,或者是路径位于raid磁盘上。例如:

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

6.3部署明细

在所有配置完成后,就必须启动有关机器上的jns守护程序。这可以通过运行 hadoop-daemon.sh start journalnode 来完成,然后就是等待守护程序在有关的机器上启动。

一旦守护程序完成启动,就必须初始同步两个ha名称节点磁盘上的元数据。

  • 如果配置的是一个新的hdfs集群,那么必须其中一个名称节点上先运行hdfs namenode -format
  • 如果早已经格式化过,或者仅仅是把一个非ha集群转换为ha集群,那么必须把元数据目录下的数据拷贝到另外一台,没有格式化的那一台节点必须运行hdfs namenode -bootstrapStandby.
  • 如果是把一个非ha名称节点转为ha节点,那么必须运行 hdfs namenode -initializeSharedEdits,这样会使用名称节点本地编辑日志目录中的数据初始化jns。

译注:关于上面的第二点和第三点的区别,第三点中提到的名称节点可能是第二名称节点,检查点节点,或者是备份节点;而第二点的应该是属于新增一个名称节点了。

然后,就可以启动两台名称节点了。

然后可以通过web浏览器来访问两个名称节点。需要注意的是,配置地址(configured address)后跟着的是"active"或者"standby".无论什么时候,一个名称几点启动的时候,其初始状态是"standby".

6.4 管理命令

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

  • transitionToActive and transitionToStandby - 传输状态到另外一个节点(active或者standay)

    注意,这个命令不提供隔离,所以要少用。应该使用hdfs haadin -failover

  • failover -开始在两个节点之间进行故障切换

    命令用户切换第一节点到第二个节点。如果 第一个节点是standby,那么可以没有错误地切换到第二个(第二个变为active).如果第一个是active的,那么会先尝试把它变为standby.如果尝试失败,那么隔离方法会被启用,直到其中一个格式尝试成功。如果有成功,那么第二个会被置为active.如果隔离都失败,那么切换失败,并返回错误信息。(译注:如果第一个是standy,还有需要切换吗?难道两个都可能是standby吗)

  • getServiceState -监测名称节点的状态,是active还是standby

  • checkHealth -检查指定节点的健康状态

    成功(健康)返回0,其它就是不健康.注:在2.8.0版本中,尚未实现,总是返回0,除非指定名称节点关闭了。

7.自动故障转移

7.1简介

以上章节描述如何手动配置故障转移。那种模式下,系统不会子弟on个触发一个故障转移,即使活动节点失败了。以下内容描述如何配置和部署一个自动故障转移。

7.2组件

自动故障转移会添加两个组件:一个zookeeper仲裁者,一个ZKFC(ZK故障转移控制器进程)。译注:为了便于书写,后文把zookeeper简写为zk

阿帕奇的zookeeper是一个高可靠服务,可用于维护少量的协调数据,通知客户数据的变更,并监控客户端的故障。HDFS的自动故障转移依赖于zookeeper的以下几个方面:

  • 故障侦测 - 集群中每个名称节点上都会运行一个zookeeper的持久会话.如果机器崩溃,那么zk会话就会过期,然后就通知其它节点应该触发故障转移了。

  • 活动节点选举 - zk提供了一个简单的机制来选择唯一一个节点作为活动节点。如果当前的活动节点完蛋,另外一个节点可能会在zk中设立一个排他锁,宣告它要成为下一个活动节点。

ZKFC是zk的新组件,属于zk的客户端,也会监控和管理名称节点的状态。每个运行名称节点的机器同时也会运行一个zkfc,zkfc负责:

  • 监控监控 - zkfc使用健康检查命令定期检查本地的名称节点(译注:原文使用的是ping,大意是提醒读者这个行为很像ping). 只要名称节点及时回应健康的状态,那么zkfc就会认为节点是健康的。如果节点崩溃,或者冻结(译注:原文是frozen),或者进入一个不健康的状态,那么zkfc就会把它标记为不健康.

  • zk会话管理- 当本地的名称节点健康的时候,zkfc会和zk保持一个打开的会话。如果本地节点是活动的,那么会话就持有一个特定的“lock” znode(译注:这个可能zk系统的一个说法,运行zkfc的节点称为znode). 这个锁会把当前节点当作一个“ephemeral”节点;如果会话过期,那么锁定的节点会被删除掉。(译注:ephemeral-本意是“短暂的瞬息的”,按照zk的设计思路,大意是总认为每个节点的状态都是可疑的,zk总是在等待着选择下一个节点。每一个名称活动且被锁定的名称节点其状态都是暂时的,随时可以被其它的节点替代,如果有必要的话)。

  • zk-基本选举 - 如果本地节点是健康的,zkfc认为没有其它节点持有一个锁定的znode,它自己会试图获取锁。如果成功,那么它就“赢得选举”,并负责启动一个故障转移,把本地节点设定为活动的名称节点。故障转移的过程类似于前文的手动方式:  首先,隔离先前的节点(如果有必要),然后本地节点转为为活动的状态.

要了解更多自动故障转移的设计细节,请参考apache hdfs jira--https://issues.apache.org/jira/browse/HDFS-2185

译注:现有版本的ha-hdfs相对比较简单,总共部署了两个名称节点,将来可能会支持更多的节点。zk可以支持许多znode

zk的监控和选举看起来还是相对简单的:每个znode不断试图证明自己ok,如果不ok,就被zk删除掉。剩下的健康znode就会争宠,成功了就切换到特定的节点。

当然,还有更多的细节。不过这不是ha的重点。

7.3部署zookeeper

在一个典型的部署中,zk守护程序运行在3到5个节点中。由于zk自己对资源要求很低,把它们和hdfs的名称节点(活动的或者等待的)部署在同样的硬件上也是可以接受的。许多人会选择把第三个zk进程和yarn资源管理器部署在一起。

强烈建议:不要和名称节点部署在一起,考虑到性能和隔离性。

zk的配置已经超过了本文的范围。我们假定你已经在3到5个节点上成功部署并运行了一个zk集群,并通过zk cli验证过了。

译注:把zk和nn部署在一起,简直就是犯罪,不如不做,但原文作者也不会强制阻止那种“勇敢”的行为。

7.4开始前准备

在开始配置自动故障转移前,我们必须关闭现有的hadoop集群。集群正在运行得时候,是无法从手动模式切换到自动模式的。

7.5配置自动故障转移

需要在hdfs-site.xml中添加以下部分:

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

<description>启动自动故障转移</description>
 </property>

在core-site.xml中添加如下:

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

<description>列出运行zk的机器和端口,以逗号分隔</description>
 </property>

译注:原文说到,还有几种配置的方式。 由于不常用,所以本人也可以少打几个字了。

7.6初始化zookeeper的ha状态

在添加了关键配置之后,下一步就是初始化zk的数据。我们可以在其中一台名称节点上运行名称来完成这个步骤:

$HADOOP_PREFIX/bin/hdfs zkfc -formatZK

这个命令的作用就是在ZK中创建一个ZNODE数据。

译注:一般人安装的时候,不一定设定了HADOOP_PREFIX的变量,多是设定HADOOP_HOME,而且一般有设定PATH,所以以上的命令可以简化为 hdfs zkfc -formatZK  ,或者简单把HADOOP_PREFIX替换为HADOOP_HOME,实在不行多设置一环境变量也可以 export HADOOP_PREFIX=$HAOOP_HOME

7.7使用start-dfs.sh启动集群

由于自动故障转移已经启用,所以start-dfs.sh脚本会自动启动ZKFC守护程序(在所有每次节点上)。当zkfc启动的时候,它们会自动选举一个活动节点。

译注:自从有了start-dfs.sh之后,启动集群变得方便了许多,不用关心在哪个节点上启动哪些命令。

7.8手动启动集群

如果是手动管理集群,请使用以下命令(在每一个名称节点上执行)

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

7.9安全访问zookeeper

如果我们运行的是一个安全集群,我们可能会想确保存储在zk中的数据也是安全的。这样可以阻止一些恶意客户端修改zk的元数据,或者触发一些错误的故障转移。

为了保全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-auth.txt的内容,内容格式如下:

digest:hdfs-zkfcs:mypassword

hdfs-zkfcs是zk的用户名称,mypassword是zk用户的密码

第二步,生成zk-acl.txt(需要和zk-auth.txt中的用户对应)

请使用以下命令生成:

[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=

把上面输出中"->"后的红色字符串整合如下: digest:hdfs-zkfcs:vlUvLnd8MlacsE80rDuu6ONESbM=:rwcda

最后,为了保证这些acl起作用,必须重新运行  hdfs zkfc -formatZK  (译注:如果一开始就配置了安全存取,那么格式化一次就可以了)

之后,就是通过zk-cli来验证:

[zk: localhost:2181(CONNECTED) 1] getAcl /hadoop-ha

'digest,'hdfs-zkfcs:vlUvLnd8MlacsE80rDuu6ONESbM= : cdrwa

7.10验证自动故障转移

一旦自动故障转移已经设置好,我们必须测试下。首先找到活动的节点-这个可以通过名称节点的http来访问获取,例如http://nn1:50070

之后,在活动的节点上搞个破坏。例如断线,kill进程,关机等等。然后看下另外一个节点的状态是否变成active了(不是马上,可能要几秒钟)。这个等待间隔取决于配置 ha.zookeeper.session-timeout.ms,默认是5秒。

如果没有成功,那么一定那么配错了。检查下zfkc的日志和名称节点的日志,或者再看看配置那里出现错误了没有。

8.自动故障转移FAQ

  • zkfc和名名称节点的启动顺序是否重要? 

    不。任何名称节点上zkfc都可以在名称节点前或者后启动  。  译注:这个是比较令人奇怪的事情,不过当ha中使用zk和多个名称节点配置之后,除非zk启动了,否则无法使用的。所以不需要关注这个问题。

  • 是否需要额外监测一些东西?

    应该更多关注每个名称节点,确保其上的zkfc是正在运行中。有些情况的zk故障,例如zkfc可能会意外退出,那么就需要确保重启zkfc。此外,必须监控zk服务器。如果zk服务器完蛋了,也无法自动故障转移。

  • zk关闭的时候发生了什么?

    如果状况集群甭快,那么就无法自动触发故障转移。然而这对hdfs没有任何影响,还是可用的. 当zk重启,hdfs会静悄悄重连zk。

译注:就这个方面而言,个人觉得oracle rac做得还是挺不错的,当然hdfs做得也还可以。

  • 是否可以指定某个名称节点为主要的?

    不。当前不允许。那个先启动,那个就是活动的。你可以选择先启动其中一个,或者关闭另外一个然后再重启来切换到其中一个为主要的点。但不能总是指定为主要的。

  • 如果已经配置了自动化的,那么如何手动故障切换?

    即使配置了自动故障转移,我们也可以使用hdfs haadmin来做手动的故障转移,效果是一样的。

9.ha HDFS 的升级/就绪/回滚

当升级HDFS某些版本的时候,有些时候新版本软件可以简单安装并重启集群。有些时候,升级hdfs,可能要求修改磁盘数据。在这种情况下,必须使用HDFS  Upgrade/Finalize/Rollback工具。在ha环境下,这个更加复杂,因为名称节点磁盘上的元数据是分布的,除了名称节点是这样,jns也是如此。这个章节描述在ha hdfs中如何使用 Upgrade/Finalize/Rollback。

为了执行一个ha升级,操作人员必须做以下事情:

  1. 正常关闭所有的名称节点,然后安装新的软件。

  2. 启动所有jns。至关重要-Upgrade/Finalize/Rollback的时候jns必须都在运行。如果期间,有任意的jns停止运行,那么操作会失败。

  3. 使用-upgrade选项启动其中一个名称节点

  4. 启动的时候,这台名称节点立即进入ACTIVE状态,然后执行对本地存储目录和共享编辑日志的升级。

  5. 然后使用-bootstrapStandby选项启动另外一个名称节点。

注意,如果想就绪或者回滚,那么只需要正常启动名称节点。

就绪一个升级, 操作人员使用‘hdfs dfsadmin -finalizeUpgrade’命令即可,其中一台名称节点执行即可。活动的那个会做共享日志的就绪工作,另外一台则会把以前的FS的磁盘信息删除掉(译注:登台下一次jns的同步).

执行回滚, 两个名称节点都需要关闭,操作人员在执行upgrade的那台上名称节点上执行roll back命令,然后那个节点会执行数据回滚。然后这个节点,再次执行正常启动,另外一台则执行  `-bootstrapStandby' .

译注:

1)升级/就绪/回滚之类的都是hdfs namenode中的几个命令。关于“Finalization”原文的意思就是为升级扫尾并打上正常标记的意思。Finalization本意是终结,但可能会让读者误会。

因为终结一个升级状态后,就是集群的就绪,所以译文使用“就绪"而不是”终结".

2) 当故障转移发生的时候,如何保证hadoop应用可以正常使用了? 由于一些应用可能直接通过直接指向其中一台名称节点,这样可能存在问题。 所以解决这个问题,要么hadoop已经提供了类似oracle的透明故障转移,要么使用api的开发人员必须考虑自己编码实现

应用的透明故障转移。由于本人并没有使用hadoop的api编程,尚不清楚这个。 也不清楚更新的版本中的是什么情况。

3)hadoop的 federation和ha是可以同时部署的,这个方面可以参考 http://www.linuxidc.com/Linux/2014-05/101181.htm

不好比较hadoop的这种ha和提高吞吐的架构,如果和oracle rac比较,个人觉得后者更加高级一些,既能提高吞吐,也可以提高可靠性,  至少对于开发人员和用户而言是这样的。

如果你的应用并不需要同时运行那么多的task,建议暂时部署ha即可。

04-14 07:10