本文是在hadoop集群部署(yarn)基础上增加的配置内容,因为那篇缺少HDFS的HA配置,在生产环境不够完整。
hadoop官方提供了两种HDFS的HA配置方案,两种方案殊途同归,但是需要的钱、精力和技术不同。
如果对HDFS架构熟悉的话(如果不熟悉,可以通过HDFS架构了解),就应该知道,NameNode通过FsImage和EditLog两个文件管理DataNode的数据,Secondary NameNode会定期合并EditLog,以减少NameNode启动时的安全检查。EditLog文件存储的是对文件的一条条的操作,也就是说,只要保证有另外一个NameNode的EditLog文件一直与当前正在运行的NameNode的EditLog文件是一样的,那就可以随时使用新的NameNode替换老的NameNode。官方目前给出的两种HA方案也大体是这样:
客观的说,Secondary NameNode也算是对NameNode的备份,但是使用Secondary NameNode需要手动处理,不如QJM和NFS两种可以自动处理简单,所以没有被列入HA解决方案中。
但是,这两种方案在部署方式上差别比较大。QJM需要启动几个JournalNode即可,NFS需要挂在一个共享存储。因为条件限制,我只能通过QJM的方式实现HDFS的HA,如果想看NFS方案,可以直接看官方文档。
<property>
<name>dfs.nameservicesname>
<value>myclustervalue>
property>
<property>
<name>dfs.ha.namenodes.myclustername>
<value>nn1,nn2value>
property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1name>
<value>s108:8020value>
property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2name>
<value>s109:8020value>
property>
<property>
<name>dfs.namenode.http-address.mycluster.nn1name>
<value>s108:50070value>
property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2name>
<value>s109:50070value>
property>
<property>
<name>dfs.namenode.shared.edits.dirname>
<value>qjournal://s108:8485;s109:8485;s110:8485/myclustervalue>
property>
ConfiguredFailoverProxyProvider
,也可以自己定义:<property>
<name>dfs.client.failover.proxy.provider.myclustername>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvidervalue>
property>
dfs.ha.fencing.methods:用于故障转移过程中,在活跃节点执行的一组脚本或Java类。HDFS集群有一条原则是:只能有一个NameNode处于活跃状态。QJM只允许一个NameNode写入JournalNode集群,所以可以避免闹裂的发生。但是故障转移过程中,还可能会有其他的问题,所以需要提供一些防护方法。需要注意的是,如果不想使用具体的防护方法,也必须提供一个脚本,比如shell(/bin/true)
。
dfs.ha.fencing.ssh.private-key-files
配置ssh key,还可以通过dfs.ha.fencing.ssh.connect-timeout
配置ssh连接超时时间。 <property>
<name>dfs.ha.fencing.methodsname>
<value>sshfencevalue>
property>
<property>
<name>dfs.ha.fencing.ssh.private-key-filesname>
<value>/root/.ssh/id_rsavalue>
property>
<property>
<name>dfs.ha.fencing.ssh.connect-timeoutname>
<value>30000value>
property>
如果对于不是标准ssh端口或相同用户的,可以在sshfence后添加用户名和端口,格式为sshfence([[username][:port]])
。
<property>
<name>dfs.ha.fencing.methodsname>
<value>shell(/path/to/my/script.sh arg1 arg2 ...)value>
property>
dfs.journalnode.edits.dir:JournalNode守护进程存储数据的本地路径。这是启动JournalNode需要配置的配置项。当然整个集群配置相同也不会有不好的影响,需要是本地绝对路径。
<property>
<name>dfs.journalnode.edits.dirname>
<value>/data/hadoop/journalvalue>
property>
ha.zookeeper.quorum
配合使用。<property>
<name>dfs.ha.automatic-failover.enabledname>
<value>truevalue>
property>
<property>
<name>fs.defaultFSname>
<value>hdfs://myclustervalue>
property>
<property>
<name>ha.zookeeper.quorumname>
<value>s109:2181,s110:2181,s111:2181value>
property>
需要首先启动JournalNode,如上面配置的,需要s108/s109/s110三个节点启动JournalNode,默认端口就是8045。启动命令是hadoop-daemon.sh start journalnode
。
JournalNode启动完成后,因为有两个NameNode节点,就需要先同步两个NameNode节点的数据。
hdfs namenode -format
格式化即可hdfs namenode -bootstrapStandby
命令。hdfs namenode -initializeSharedEdits
将原有的NameNode日志写入JournalNode中。因为上面配置了自动故障转移,所以需要在Zookeeper中初始化HA状态。执行命令hdfs zkfc -formatZK
。
直接使用start-dfs.sh
命令启动NameNode、DataNode,以及ZKFS进程,启动成功之后就可以通过s108:50070和s109:50070访问web页面查看具体哪个NameNode是Active或Standby状态的了。
启动的时候可以注意到,启动过程没有启动Secondary NameNode,这是用为HA不会启动Secondary NameNode。也就是master配置文件配置内容无效了。
可以通过hdfs haadmin
命令进行管理。具体查看官网说明。
参考
1. HDFS High Availability Using the Quorum Journal Manager
2. HDFS High Availability
个人主页: http://www.howardliu.cn
个人博文: 使用QJM实现HDFS的HA
CSDN主页: http://blog.csdn.net/liuxinghao
CSDN博文: 使用QJM实现HDFS的HA