搭建hadoop的高可用性,hadoop版本为2.6.5。hadoop的高可用配置有两种方法,以下是我选择配置的Quorum Journal Manager (QJM)的方法。
Quorum的高可用需要启动奇数个(3、5、7等)JournalNodes节点进行日志的处理,活动NameNode节点负责进行写日志,而备份NameNode节点则负责从JournalNodes节点中读取数据,从而实现主备份之间的数据同步。配置JournalNode节点后还不能进行自动故障转移,只能手动进行故障转移,想做到自动故障转移,还需要配置zookeeper。
除了JournalNode需要奇数外,zookeeper的服务也需要奇数个,我这选择配置的是3个,3个JournalNode,3个zookeeper服务。所以本次搭建的集群为6个节点即启动6个docker容器,第一个NameNode节点(IP:172.17.0.2),第二个NameNode节点(IP:172.17.0.3),以及一个ResourceManager节点(IP:172.17.0.4),同时分别在这三个节点上启动JournalNode和zookeeper服务;另外三个为DataNode节点。 在上一次《Docker之Hadoop普通集群搭建(五》搭建的docker镜像基础上,主要修改以下hadoop配置文件参数:
hdfs-site.xml:
<configuration>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/data/hdfs/name</value>
<final>true</final>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/data/hdfs/data</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
<property>
<name>dfs.namenode.datanode.registration.ip-hostname-check</name>
<value>false</value>
</property>
<!-- 以下为新增参数 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>172.17.0.2:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>172.17.0.3:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>172.17.0.2:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>172.17.0.3:50070</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://172.17.0.2:8485;172.17.0.3:8485;172.17.0.4:8485/mycluster</value>
</property>
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<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.journalnode.edits.dir</name>
<value>/var/hadoop/journal</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
core-site.xml:
<configuration>
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>file:/data/tmp</value>
</property>
<!-- 以下为新增参数 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>172.17.0.2:2181,172.17.0.3:2181,172.17.0.4:2181</value>
</property>
</configuration>
yarn-site.xml:
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>172.17.0.4:8031</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>172.17.0.4:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>172.17.0.4:8034</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>172.17.0.4:8088</value>
</property>
</configuration>
另外是zookeeper配置,zk的配置相对简单,在官网下载压缩包并进行解压,再简单修改下配置文件即可,例如复制一份zoo_sample.cfg文件,并改名为zoo.cfg,添加以下内容:
server.1=172.17.0.2:2888:3888
server.2=172.17.0.3:2888:3888
server.3=172.17.0.4:2888:3888
在zoo.cfg中dataDir配置的路径下创建myid文件,myid文件内保存对应的id,比如上面配置server.1=172.17.0.2:2888:3888,则需要在172.17.0.2主机上创建的myid文件保存1,其它节点类似创建myid文件即可。 通过以上配置就基本完成了高可用性配置了,接下来就是启动了。
hadoop的启动这里经常会使用到start-dfs.sh命令,其中start-yarn.sh命令启动ResourceManager和NodeManager进程。其它剩下的进程都通过start-dfs.sh来进行,如果某些进程没法启动成功,则肯定存在某些步骤未执行或者配置存在错误,进行相关操作或修改好后,再次执行start-dfs.sh命令启动,如果还有不成功的,则继续排除继续执行start-dfs.sh命令,直到所有进程启动成功。
启动NameNode前必须进行格式化,而在高可用中,需要先启动JournalNode后再格式化,否则无法成功格式化,所以先执行start-dfs.sh启动JournalNode后再执行hdfs namenode -format,然后再执行start-dfs.sh启动NameNode节点。
此时会发现,只在当前格式化后的节点上成功启动了NameNode进程,另一个节点则启动失败,如果查看相关log则会发现抛出未格式化的异常。这时需要在启动NameNode的节点上执行hdfs namenode -bootstrapStandby命令完成格式化,此命令的执行必须启动第一个NameNode之后,否则无法成功格式化第二个节点。最后再执行start-dfs.sh命令,成功启动第二个NameNode节点。
以上完成了NameNode和DataNode的启动,但分别打开两个NameNode的web发现,两个NameNode节点的状态都为standby,现在还不具备高可用性,无法自动故障转移,工作还得继续。
首先需要启动zookeeper服务,分别在预先分配好的三台主机上执行zkServer.sh start启动zookeeper服务,zkServer.sh status可以查看各个服务的状态。接着在其中一台NameNode主机上执行hdfs zkfc -formatZK在zookeeper上创建znode,log中的Successfully created /hadoop-ha/mycluster in ZK表示创建成功,jps查看发现多了QuorumPeerMain。再执行start-dfs.sh启动ZKFC守护进程DFSZKFailoverController。
到此就已经完成了所有的启动了,在分别刷新NameNode的web,会发现其中一个为active状态,另一个为standby状态。
自动故障转移测试,先往hdfa上传几个文件,并能在hdfs上查看到上传后的文件,然后退出active状态容器,再次启动容器,删除NameNode节点格式化后的数据,让再次启动的容器相当于新加入的机器,启动zookeeper服务,执行hdfs namenode -bootstrapStandby格式化节点,start-dfs.sh启动集群,再查看hdfs发现的确还存在之前上传的文件,下载查看内容也一致,说明hadoop的高可用性已生效,配置成功。