文章目录
- 背景
- 高可用改造
- 方案实施
- 环境准备
- 配置文件修改
- 应用配置
- 集群状态验证
- 高可用验证
背景
假定目前有3台zookeeper服务器,分别为zk-01/02/03,DataNode服务器若干;
目前HDFS集群的Namenode没有高可用配置,Namenode和Secondary Namenode同时位于zk-03上,
且Secondary Namenode的作用是辅助Namenode恢复,并不是Namenode的高可用备份。
高可用改造
集群规划
zk-01 | zk-02 | zk-03 |
---|---|---|
Active NameNode | Standby NameNode | |
JournalNode | JournalNode | JournalNode |
ZK Failover Controller | ZK Failover Controller |
Hadoop版本为3.0之前,仅支持启用单个Standby Namenode。Hadoop版本3.0后支持启用多个Standby Namenode。
方案实施
环境准备
- 关闭防火墙
- zk-01/02/03之间配置ssh免密登录
- 配置jdk环境变量
配置文件修改
-
hadoop-2.7.3/etc/hadoop/core-site.xml
<configuration> <property> <name>fs.defaultFS</name> <!-- delete next line --> <value>hdfs://zk-03:9000</value> <!-- delete --> <!-- delete done --> <!-- add next line --> <value>hdfs://hacluster</value> <!-- add done --> </property> <property> <name>io.file.buffer.size</name> <value>131072</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/data/0/hadoop/hadoop/tmp</value> </property> <!-- add next 5 lines --> <property> <name>ha.zookeeper.quorum</name> <value>zk-01:2181,zk-02:2181,zk-03:2181</value> <description>指定zookeeper地址</description> </property> <!-- add done --> </configuration>
-
hadoop-2.7.3/etc/hadoop/hdfs-site.xml
<configuration> <!-- add next multi-lines --> <property> <name>dfs.nameservices</name> <value>hacluster</value> <description>指定hdfs的nameservice为ns,需要和core-site.xml中的保持一致</description> </property> <property> <name>dfs.ha.namenodes.hacluster</name> <value>namenode1,namenode2</value> <description>hacluster下面有两个NameNode</description> </property> <property> <name>dfs.namenode.rpc-address.hacluster.namenode1</name> <value>zk-01:9000</value> </property> <property> <name>dfs.namenode.http-address.hacluster.namenode1</name> <value>zk-01:50070</value> </property> <property> <name>dfs.namenode.rpc-address.hacluster.namenode2</name> <value>zk-02:9000</value> </property> <property> <name>dfs.namenode.http-address.hacluster.namenode2</name> <value>zk-02:50070</value> </property> <property> <name>dfs.ha.fencing.methods</name> <value>sshfence</value> <description>配置隔离机制,同一时刻只有一个Namenode对外响应</description> </property> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/home/hadoop/.ssh/id_rsa</value> <description>使用隔离机制时需要ssh免登陆</description> </property> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> <description>开启NameNode故障时自动切换</description> </property> <property> <name>dfs.client.failover.proxy.provider.hacluster</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> <description>配置失败自动切换实现方式</description> </property> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://zk-01:8485;zk-02:8485;zk-03:8485/hacluster</value> <description>指定NameNode的元数据在JournalNode上的存放位置</description> </property> <property> <name>dfs.journalnode.edits.dir</name> <value>/data/0/hadoop/hadoop/journal</value> <description>指定JournalNode在本地磁盘存放数据的位置</description> </property> <!-- add done --> <property> <name>dfs.replication</name> <value>2</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/data/0/hadoop/hadoop/name</value> </property> <property> <name>dfs.blocksize</name> <value>268435456</value> </property> <property> <name>dfs.namenode.handler.count</name> <value>100</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/data/0/hadoop/hadoop/data,/data/1/hadoop/hadoop/data,/data/2/hadoop/hadoop/data,/data/3/hadoop/hadoop/data,/data/4/hadoop/hadoop/data,/data/5/hadoop/hadoop/data,/data/6/hadoop/hadoop/data,/data/7/hadoop/hadoop/data,/data/8/hadoop/hadoop/data,/data/9/hadoop/hadoop/data,/data/10/hadoop/hadoop/data,/data/11/hadoop/hadoop/data</value> </property> </configuration>
应用配置
- 登录zk-03
$ scp -r /home/hadoop/hadoop-2.7.3 zk-02:/home/hadoop/
$ scp -r /home/hadoop/hadoop-2.7.3 zk-01:/home/hadoop/
# 停止现有HDFS集群的服务
$ hdfs/sbin/stop-dfs.sh
- zk-01/02/03: 全部启动JournalNode
$ hdfs/sbin/hadoop-daemon.sh start journalnode
- zk-01: 初始化并启动namenode1、zkfc
# 初始化并启动namenode1
$ hdfs/bin/hdfs namenode -format
$ hdfs/bin/hdfs namenode -initializeSharedEdits
$ hdfs/sbin/hadoop-daemon.sh start namenode
# 在ZK中初始化ha集群的信息
$ hdfs/bin/hdfs zkfc -formatZK
- zk-02:启动namenode2、zkfc
# 同步zk01上namenode的元数据信息并启动namenode2
$ hdfs/bin/hdfs namenode -bootstrapStandby
$ hdfs/sbin/hadoop-daemon.sh start namenode
# 在ZK02中同步ha集群的信息
$ hdfs/bin/hdfs zkfc -formatZK
- zk-01: 启动集群中其他服务,包括datanode
$ hdfs/sbin/start-dfs.sh
集群状态验证
- 登录zk-01/02,分别执行
jps
, 结果中应存在:- PID1 JournalNode
- PID2 NameNode
- PID3 DFSZKFailoverController
- 若不存在JournalNode进程则执行:
sbin/hadoop-daemon.sh start journalnode
- 若不存在DFSZKFailoverController进程则执行:
sbin/hadoop-daemon.sh start zkfc
- 若不存在NameNode进程则执行:
sbin/hadoop-daemon.sh start namenode
- 登录zk-03,执行
jps
,结果中应存在:- PID JournalNode
-
若不存在JournalNode进程则执行:
sbin/hadoop-daemon.sh start journalnode
- 在任意DataNode服务器上,执行
jps
,结果中应存在:- PID1 DataNode
-
若不存在DataNode进程则执行:
sbin/hadoop-daemon.sh start datanode
高可用验证
-
登录zk-01,查看namenode1的状态:
bin/hdfs haadmin -getServiceState namenode1
,输出结果应为active;若上述结果为standby,可以执行如下命令将主namenode切换为namenode1:
bin/hdfs haadmin -transitionToActive --forcemanual namenode1
再次执行命令查看namenode1和namenode2的状态:
bin/hdfs haadmin -getServiceState namenode1
,输出应为active;bin/hdfs haadmin -getServiceState namenode2
,输出应为standby。 -
登录zk-01,停止namenode1:
bin/hdfs --daemon stop namenode
zkfc进程应自动随之停止,执行jps
,结果中不存在NameNode和DFSZKFailoverController。
查看namenode2的状态:
bin/hdfs haadmin -getServiceState namenode2
,结果应为active。 -
重新启动namenode1:
bin/hdfs --daemon start namenode
查看namenode1的状态:bin/hdfs haadmin -getServiceState namenode1
,结果应为standby。此时可以使用第1步中切换主节点的命令将主节点切换到namenode1。