您的位置:首页 > 大数据 > Hadoop

HDFS2.0 HA完整配置过程

2014-08-05 15:38 399 查看
HDFS HA配置的完整步骤

部分内容参考了这篇文章: http://blog.csdn.net/dmcpxy/article/details/18256607 。其中配置文件时基于我的集群信息做的,还增加了配置中遇到的问题和解决办法。

最近了解了Hadoop后,又开始涉及Hadoop 2.0相关的知识,所以后续我会陆陆续续把2.0相关的一些知识和学习总结整理上来。

这里是QJM方式的HA配置,众所周知,HDFS HA一般是基于NFS公共存储的,这里不采用NFS。

主要步骤:

1. zookeeper集群配置

2. HDFS HA参数配置

3. HDFS HA启动

4. 验证测试

1. zookeeper集群配置


说明: 我是在2台机器上做的配置,貌似zookeeper推荐用奇数台机器进行搭建,一般选3台。所以两台不推荐啊不推荐。

下载zookeeper的压缩包,并且解压,我的安装包目录是/search/zookeeper/zookeeper-3.4.5/,因为是HDFS 2.0,所以相应的zookeeper的版本也不能太低,免得出现兼容性问题。
(1) 首先建立zookeeper的数据目录,比如:

mkdir /search/zookeeper/dataDir

(2) 同时建立日志存放目录:

mkdir /search/zookeeper/dataDir/logs/

(3) 在zookeeper安装包中,/conf下的zoo_sample.cfg拷贝一份,命名为zoo.cfg,这是zookeeper的配置文件:

cp zoo_sample.cfg zoo.cfg

(4) 在zoo.cfg文件是进行配置:

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/search/zookeeper/dataDir/

dataLogDir=/search/zookeeper/dataDir/logs/

clientPort=21810

#server.id in cluster = ip:port used in communicating with leader : port used when choosing a new leader

server.1=10.14.131.47:28880:38880

server.2=10.14.135.11:28880:38880

(5) 在每台服务器的dataDir目录下分别创建一个叫myid的文件,内容分别是1,2,如:

#在10.14.131.47上执行如下命令

echo 1 >/search/zookeeper/dataDir/myid

#在10.14.135.11上执行如下命令

echo 2 >/search/zookeeper/dataDir/myid

(6) 最后就是分别启动zookeeper服务了:

./bin/zkServer.sh start

(7) 通过jps命令可以检查是否启动成功:

1239 QuorumPeerMain

#看到QuorumPeerMain进程就表示zookeeper启动成功了。

(8) 测试zookeeper集群是否建立成功,在安装包目录下执行以下命令即可,如无报错表示集群创建成功:

./bin/zkCli.sh -server localhost:21810

2. HDFS2.0 HA参数配置

HA相关的配置是在core-site.xml和hdfs-site.xml中,当把这两个配置文件修改完成后,需要停止hadoop服务,然后同步修改后的配置信息到每个节点上。

说明: 这里的配置,都是基于已经成功配置了Hadoop 2.0集群的前提下,所以其他的一些配置信息没有列出。

(1) core-site.xml

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

<property>
<name>ha.zookeeper.quorum</name>
<value>10.14.131.47:21810,10.14.135.11:21810</value>
</property>

<property>
<name>ha.zookeeper.session-timeout.ms</name>
<value>1000</value>
<description>ms</description>
</property>


(2) hdfs-site.xml

<!-- HA config start -->
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>

<!-- the name service -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
<description>Logical name for this newnameservice</description>
</property>

<!-- the node in this name service -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
<description>Unique identifiers for each NameNode in thenameservice</description>
</property>

<!-- the rpc port of each node -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>10.14.143.83:8022</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>10.14.131.47:8022</value>
</property>

<!-- the http address of each namenode -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>10.14.143.83:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>10.14.131.47:50070</value>
</property>

<!-- shared storage -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://10.14.131.47:8485;10.14.135.11:8485/mycluster</value>
</property>

<!-- the agent for HA auto switch -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>

<!-- the fencing mathod -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>

<!-- journalnode config -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/search/hadoop01/journalnode/</value>
</property>
<!-- <property>
<name>dfs.journalnode.rpc-address</name>
<value>0.0.0.0:20022</value>
</property> -->

<!-- must be the HA auto switch or not -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>

<!-- HA config end -->


3. HDFS HA启动

(1) 启动zookeeper集群: 在每个zookeeper的机器上执行:

./bin/zkServer.sh start

#据说集群会自动把第一个启动的机器作为leader。who knows ~~

(2) 在某一个namenode节点执行如下命令,创建命名空间

./bin/hdfs zkfc -formatZK

(3) 在各个节点用如下命令启日志程序

./sbin/hadoop-daemon.sh start journalnode

#如果Hadoop集群比较大的话,这真是个吃力不讨好的工作。所以我写了个脚本来实现它。

(4) 在主namenode节点用./bin/hadoopnamenode -format格式化namenode和journalnode目录

./bin/hadoop namenode -format mycluster

#namenode节点在初始化时,也将自己的edits文件共享到了journalnode上。

(5) 在主namenode节点启动namenode进程

./sbin/hadoop-daemon.sh start namenode

(6) 在备节点启动备namenode进程

a) ./bin/hdfs namenode –bootstrapStandby

#这个命令是把备namenode节点的目录格式化,并且把主namenode的元数据和journalnode上的edits文件同步过来,从而使元数据和主namenode保持一致,并且这个命令不会把journalnode目录再格式化。

ERROR: 不过我在执行bootstrapStandby时失败了,具体失败的体现是下一步启动备namenode失败,报错信息是缺少$dfs.tmp.dir/data/下的name目录。因为name目录下保存的都是namenode的基本元数据,所以说明这一步的格式化没有成功。

SOLUTION:
手工把主namenode上的元数据($dfs.namenode.name.dir下的所有数据)拷贝到备namenode下的同目录下,然后再执行bootstrapStandby.

b) ./sbin/hadoop-daemon.sh start namenode

#启动备namenode。

(7) 在两个namenode节点都启动ZKFC:

./sbin/hadoop-daemon.sh start zkfc

#启动DFSZKFailoverController,也就是用于监控namenode并且保持HA状态的那个watchdog。

(8) 在所有datanode节点都执行以下命令启动datanode

./sbin/hadoop-daemon.sh start datanode

#这个步骤略坑爹,因为节点很多。最好直接在namenode节点上执行 sbin/hadoop-daemons.sh start datanode 启动。

ERROR:
启动Datanode可能失败,失败报错信息为

2014-03-13 11:26:30,788 FATAL org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for block pool Block pool BP-1257313099-10.10.208.38-1394679083528 (storage id DS-743638901-127.0.0.1-50010-1394616048958)
service to Linux-hadoop-38/10.10.208.38:9000

java.io.IOException: Incompatible clusterIDs in /usr/local/hadoop/tmp/dfs/data: namenode clusterID = CID-8e201022-6faa-440a-b61c-290e4ccfb006; datanode clusterID = clustername

错误提示很明显,Datanode节点初始化失败,和hadoop.tmp.dir目录有关系。一般是因为,我们的Hadoop集群不是首次启动,所以版本信息产生冲突。

SOLUTION:
对比master节点上dfs.namenode.name.dir目录下,current文件夹中的VERSION文件的内容,和slave节点上hadoop.tmp.dir目录下,data/current/目录下的VERSION文件的内容,会发现他们的内容不一致,很有可能是这个VERSION是Datanode在没有配置HA之前的集群中使用的VERSION,所以Datanode无法正常启动。删除slave上的VERSION文件,再启动就成功了。

(9) 通过web界面查看两个namenode的状态,如果都处在standby状态的话,就把其中一个namenode切换成Active状态。

hdfs haadmin -failover --forcefence --forceactive <serviceId> <serviceId>

#这个命令的作用我不是很清楚,到底哪个serviceId会被切换成Active。或者用下面的命令:

bin/hdfs haadmin -transitionToActive nn1

此时进行检查,HDFS集群应该已经全部正常启动了。下次再启动时,直接执行./sbin/start-dfs.sh就好。关闭直接执行./sbin/stop-dfs.sh就好。

4. 测试HA的功能

(1) 在Active namenode节点上先jps找到namenode的进程号,然后kill -9杀死namenode进程。观察standby namenode节点的状态变化。

jps

kill -9 pid_namenode

(2) 观察standby节点是否自动切换成了Active:

通过web界面查看,括号内显示的状态从standby变成了active;

观察zkfc日志(logs/.....-zkfc.......log),最后一行出现如下日志,表示切换成功:

INFOorg.apache.hadoop.ha.ZKFailoverController: Successfully transitioned NameNodeat hd0/192.168.111.130:53310 to active state

(3) 启动被kill掉的namenode

./sbin/hadoop-daemon.sh start namenode

(4) 观察该namenode节点的状态:

通过web界面查看,括号内显示的状态为standby;

观察zkfc日志(logs/.....-zkfc.......log),最后一行出现如下日志,表示该节点作为standby节点已经正常启动:

INFOorg.apache.hadoop.ha.ZKFailoverController: Successfully transitioned NameNodeat hd2/192.168.111.132:53310 to standby state
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: