本文是在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方案也大体是这样:
QJM:the Quorum Journal Manager,翻译是法定经济管理人,实在没法想象,所以大家都亲切的称之为QJM。这种方案是通过JournalNode共享EditLog的数据,使用的是Paxos算法(没错,zookeeper就是使用的这种算法),保证活跃的NameNode与备份的NameNode之间EditLog日志一致。NFS:Network File System 或 Conventional Shared Storage,传统共享存储,其实就是在服务器挂载一个网络存储(比如NAS),活跃NameNode将EditLog的变化写到NFS,备份NameNode检查到修改就读取过来,是两个NameNode数据一致。客观的说,Secondary NameNode也算是对NameNode的备份,但是使用Secondary NameNode需要手动处理,不如QJM和NFS两种可以自动处理简单,所以没有被列入HA解决方案中。
但是,这两种方案在部署方式上差别比较大。QJM需要启动几个JournalNode即可,NFS需要挂在一个共享存储。因为条件限制,我只能通过QJM的方式实现HDFS的HA,如果想看NFS方案,可以直接看官方文档。
dfs.ha.fencing.methods:用于故障转移过程中,在活跃节点执行的一组脚本或Java类。HDFS集群有一条原则是:只能有一个NameNode处于活跃状态。QJM只允许一个NameNode写入JournalNode集群,所以可以避免闹裂的发生。但是故障转移过程中,还可能会有其他的问题,所以需要提供一些防护方法。需要注意的是,如果不想使用具体的防护方法,也必须提供一个脚本,比如shell(/bin/true)。
sshfence:通过ssh方式连接活跃NameNode,并kill掉进程。所以还需要通过dfs.ha.fencing.ssh.private-key-files配置ssh key,还可以通过dfs.ha.fencing.ssh.connect-timeout配置ssh连接超时时间。 <property> <name>dfs.ha.fencing.methods</name> <value>sshfence</value> </property> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property> <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>30000</value> </property>如果对于不是标准ssh端口或相同用户的,可以在sshfence后添加用户名和端口,格式为sshfence([[username][:port]])。
shell:运行任意的脚本来进行防护。我是使用sshfence方式配置的,所以下面就列出配置格式,具体信息查看官网。 <property> <name>dfs.ha.fencing.methods</name> <value>shell(/path/to/my/script.sh arg1 arg2 ...)</value> </property>dfs.journalnode.edits.dir:JournalNode守护进程存储数据的本地路径。这是启动JournalNode需要配置的配置项。当然整个集群配置相同也不会有不好的影响,需要是本地绝对路径。
<property> <name>dfs.journalnode.edits.dir</name> <value>/data/hadoop/journal</value> </property> dfs.ha.automatic-failover.enabled:自动故障转移,该配置向需要与core-site.xml中的ha.zookeeper.quorum配合使用。 <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property>需要首先启动JournalNode,如上面配置的,需要s108/s109/s110三个节点启动JournalNode,默认端口就是8045。启动命令是hadoop-daemon.sh start journalnode。
JournalNode启动完成后,因为有两个NameNode节点,就需要先同步两个NameNode节点的数据。
如果是全新的HDFS集群,这个时候直接hdfs namenode -format格式化即可已经格式化或是从非HA设置为HA的集群,需要把格式化后的NameNode节点的数据拷贝到为格式化节点上。未格式化NameNode节点执行hdfs namenode -bootstrapStandby命令。如果是从非HA到HA的配置,需要执行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
主页: http://blog.csdn.net/liuxinghao
博文: 使用QJM实现HDFS的HA