【Hadoop】基于QJM的HDFS高可用系列二 - 部署

官方文档翻译,官方链接
翻译水平有限,且以学习为主,请谅解和提意见。
转载请注明出处!!!

接着上一篇发布的文章继续翻译。这次从部署章节开始。

部署

配置概述

类似联邦的配置,HA的配置向后兼容,且允许不改变现有的单NameNode配置集群的配置。如此设计新的配置,以致于在集群所有节点可以使用相同的配置,不需要基于此类型的节点部署不同的配置文件到不同的机器上。
像HDFS联邦机制一样,HA集群重用nameservice ID来标识一个单独的HDFS实例,该实例实际上由多个NameNode组成。另外,被称为NameNode ID新的抽象加入到HA。在集群中每个不同的NameNode都有一个不同的NameNode ID以示区别。对于所有的NameNode支持单一的配置文件,相关的配置参数使用nameservice ID为后缀,与NameNode ID等同。

配置细节

配置HA NameNode,必须增加几个配置项到hdfs-site.xml配置文件中。
对于你设置这些配置的顺序并不重要,但是对于dfs.nameservices和dfs.ha.namenodes选项所选择的值是重要的。[nameservice ID]将决定后面那些配置项的key。因此,设置剩下的配置项前,你将要决定这些值。

  • dfs.nameservices – 新的nameservice的逻辑名
    为这个nameservice定义一个逻辑名,例如“mycluster”,且这个配置项的值即是这个逻辑名。这个名字可以任意定义。它将被用于配置和在集群中作为绝对HDFS路径的认证组件。
    注意:如果同时使用了HDFS联邦机制,这个配置将被设置成包括其它nameservices、HA或其它的一个列表,以逗号分割的列表。
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
  • dfs.ha.namenodes.[nameservice ID] – 对于在nameservice中的每个Namenode的唯一标识
    使用逗号分隔的NameNode ID列表进行配置。这是DataNode确定集群中所有的NameNode。例如,如果之前你使用“mycluster”定义了nameservice ID,且可以使用“nn1”和“nn2”作为各自的NameNode ID,将配置如下:
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>

注意:目前,可以为每个nameservice配置最多两个NameNode。

  • dfs.namenode.rpc-address.[nameservice ID].[name node ID] – 每个Name Node的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>
  • dfs.namenode.http-address.[nameservice ID].[name node ID] – 每个NameNode的HTTP地址和监听端口
    类似上面RPC地址,设置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 – 标识JNs(NameNode将读/写的编辑记录存入JNs)组的URI
    JournalNode提供共享编辑存储,有Active NameNode写入,Standby NameNode读取且保持更新有Active NameNode作出的所有文件系统的变化,这里配置一个所有JournalNode地址的地址串。虽然必须指定几个JournalNode地址,仅配置一个URI串。如下形式:
qjournal://*host1:port1*;*host2:port2*;*host3:port3*/*journalId*

对于这个nameservice,这个Journal ID是唯一的标识,允许一个单一的JournalNode集为联邦命名系统提供存储。虽然不是必须的,但是为journal ID重用nameservice ID是个好建议。
例如,对于这个集群JournalNode运行在“node1.example.com”,“node2.example.com”和“node3.example.com”机器上,且nameservice 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类
    配置Java类名,该类将有DFS客户端使用,决定哪个NameNode是当前Active的,因此此NameNode是当前正在服务于客户端请求。当前Hadoop唯一实现是ConfiguredFailoverProxyProvider,因此使用这个,除非进行自定。例如:
<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类的列表。在故障转移期间,将用于fence这个Active NameNode。
    对于理想状态的系统来说,在任意时刻有且仅有一个NameNode是在Active状态下。重要的是,当时用QJM,永远仅有一个NameNode将被允许写入JNs,因此没有可能由于脑裂现象破环文件系统元数据。但是,当故障转移发生时,原Active NameNode到客户端的读请求服务仍然可能,这可能是过时的,因为直到NameNode停止的这段时间,NameNode仍尝试向JNs写入。基于这个原因,当时用QJM时仍然需要配置一些fencing方法。然而,在fencing机制失败事件中提高系统可用性。配置一个fencing方法最明智是在fencing方法列表最后确保返回成功。注意如果没有选择没有实际fencing方法,还必须配置一些设置,比如:“shell(/bin/true)”
    fencing方法配置一个以回车分割的列表,将按顺序执行,直至一个fencing明确返回成功。hadoop提供两种方法:shellsshfence。对于自定义fencing方法的实现,参看org.apache.hadoop.ha.NodeFencer类。
    1)sshfence – SSH到Active NameNode并kill掉这个进程
    sshfence选项SSH到目标节点,使用fuser杀掉在TCP端口监听的服务进程。为了可以让这个fencing选项能够工作,必须可以在没有密码的情况下,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,也可以配置超时,单位ms;对于SSH,fencing方法过时后,将被认为失败。配置如下:

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

2)shell – 运行一个shell脚本,fence这个Active NameNode
Shell fencing方法运行一个任意的shell脚本,配置如下:

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

“(”和“)”之间的字符串直接传递到bash shell,中间不能包含任何关闭括号。
shell命令运行在一个包含所有当前Hadoop配置的环境里,使用配置键时使用’_’替换’.’。
另外,如下变量引用目标机器执行fencing:

变量名说明
$target_host被fencing的节点主机名
$target_port被fencing的节点的IPC端口
$target_address包含上述两个变量,形如:host:port
$target_nameserviceid被fencing的NN的nameservice ID
$target_namenodeid被fencing的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,fencing被确定为成功。如果返回其它退出码,这个fencing没有成功,在列表中的下一个fencing将被执行。
注意:fencing方法没有实现任何超时。如果超时是必须的,应该在shell脚本中实现(例如通过子shell杀掉父进程的秒数)。

  • fs.defaultFS – 当没有给定时,Hadoop FS客户端使用的默认路径前缀
    可选,现在可以使用HA逻辑URI配置默认的Hadoop客户端路径。比如之前使用”mycluster”定义的nameservice ID,定义为HDFS路径认证部分的值。在core-site.xml文件中形如:
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
  • dfs.journalnode.edits.dir – JournalNode进程存储它的本地状态的路径
    这是在JournalNode节点机器上的绝对路径,编辑日志和其它本地状态将本存储在这个路径下。可以使用单一路径作为配置。这些数据的冗余是由索格JN提供的,或者把这个目录配置在本地的RAID上。例如:
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/path/to/journal/node/local/data</value>
</property>

部署细节

在准备好所有必须的配置项后,必须启动JournalNode守护进程。使用hadoop-daemon.sh start journalnode命令启动,并等待每个相关的机器上的进程启动完成。
一旦JournalNode已经启动完成,必须初始化同步两个NameNode在磁盘的元数据。

  • 如果是设置一个新的HDFS集群,需要首先在其中一个NameNodes运行如下命令:
hdfs namenode -format
  • 如果已经格式化了NameNode,或是转换一个非HA集群到HA集群,需要将现有的NameNode元数据复制到其它未格式化的NameNode上,要在未格式化的NameNode运行如下命令:
hdfs namenode -bootstrapStandby

运行该命令,确保JN(由dfs.namenode.shared.edits.dir作为配置)包含足够的编辑记录事务支持两个NameNode启动。

  • 如果转换一个非HA的NameNode成为HA的NameNode,需要运行如下命令:
hdfs namenode -initializeSharedEdits

这个命令将从本地NameNode编辑记录目录初始化JN使用的编辑记录数据。
现在可以启动两个HA的NameNode,就像启动一般的NameNode。
可以分别通过配置的HTTP地址访问每个NameNode的web页面。将注意到配置地址显示NameNode的HA状态(’active’ 或’standby’)。HA的NameNode初始状态任何时候都是Standby。

    原文作者:mikeliuy
    原文地址: https://www.jianshu.com/p/0212cd20b276
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞