Hadoop-HDFS(十一) Hadoop NameNode HA 高可用

11 Hadoop NameNode HA

11.1  概述

HDFS 2.x

解决 HDFS 1.0 中单点故障内存受限问题,联邦 HA

HDFS2.x 中 Federation 和 HA 分离,HA 只能有两个 NameNode

解决单点故障

HDFS HA:通过主备 NameNode 解决

如果主 NameNode 发生故障,则切换到备 NameNode 上。

解决内存受限问题

HDFS Federation(联邦);水平扩展,支持多个 NameNode;

(1)所有 NameNode 共享所有 DataNode 存储资源

(2)每个 NameNode 分管一部分目录;

11.1.1 手动 HA

fsimage+edits log 需要

由 StandbyNameNode 做合并工作

fsimage 推送的时机可以通过参数来调整:
dfs.namenode.checkpoint.period    1 小时
dfs.namenode.checkpoint.txns       100 0000 事务
dfs.namenode.checkpoint.check.period    3s

dfs.namenode.num.checkpoints.retained
dfs.ha.tail-edits.period

1、一个 NameNode 进程处于 Active 状态,另 1 个 NameNode 进程处于 Standby 状态。Active 的 NameNode 负责处理客户端的请求。

2、Active 的 NN 修改了元数据之后,会在 JNs 的半数以上的节点上记录这个日志。Standby 状态的 NameNode 会监视任何对 JNs 上 edit log 的更改。一旦 edits log出现更改,Standby 的 NN 就会根据 edits log 更改自己记录的元数据。

3、当发生故障转移时,Standby 主机会确保已经读取了 JNs 上所有的更改来同步它本身记录的元数据,然后由 Standby 状态切换为 Active 状态。

4、为了确保在发生故障转移操作时拥有相同的数据块位置信息,DNs 向所有 NN 发送数据块位置信息和心跳数据。

5、JNs只允许一台NameNode向JNs写edits log数据,这样就能保证不会发生“脑裂”。

11.1.2 自动 HA

11.1.3 总结

主备 NameNode

解决单点故障(属性,位置)元数据

主 NameNode 对外提供服务,备 NameNode 同步主 NameNode 元数据,以待切换

所有 DataNode 同时向两个 NameNode 汇报数据块信息(位置)

JNN:集群(属性)同步 edits log

standby:备,完成了 edits.log 文件的合并产生新的 fsimage,推送回 ANN

两种切换选择

手动切换:通过命令实现主备之间的切换,可以用 HDFS 升级等场合

自动切换:基于 Zookeeper 实现

基于 Zookeeper 自动切换方案

ZooKeeper Failover Controller:监控 NameNode 健康状态,并向 Zookeeper
注册 NameNode。NameNode 挂掉后,ZKFC 为 NameNode 竞争锁,获得 ZKFC 锁的
NameNode 变为 active

zookeeper 的分布式锁,keepalived

11.2 NameNode 自动 HA 集群搭建

11.2.1 规划

11.2.2 搭建步骤

如何让 ssh 不提示 fingerprint 信息,然后输入 yes 或者 no

/etc/ssh/ssh_config(客户端配置文件) 区别于 sshd_config(服务端配置文件)

11.2.2.1 四台服务器之间免密登录

四台服务器之间互相均可以免密登录

a、 首先在四台服务器上都要执行:

ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa

b、在 node1 上将 node1 的公钥拷贝到 authorized_keys 中:

cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

将该文件拷贝给 node2:

scp ~/.ssh/authorized_keys node2:/root/.ssh/

c、在 node2 中将 node2 的公钥追加到 authorized_keys 中:

cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

将该文件拷贝给 node3:

scp ~/.ssh/authorized_keys node3:/root/.ssh/

d、在 node3 中将 node3 的公钥追加到 authorized_keys 中:

cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

将该文件拷贝给 node4:

scp ~/.ssh/authorized_keys node4:/root/.ssh/

e、在 node4 中将 node4 的公钥追加到 authorized_keys 中:

cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

将该文件拷贝给 node1、node2、node3:

scp ~/.ssh/authorized_keys node1:/root/.ssh/
scp ~/.ssh/authorized_keys node2:/root/.ssh/
scp ~/.ssh/authorized_keys node3:/root/.ssh/

11.2.2.2 JDK  安装环境变量配置

首先将 node1 中的 hadoop-2.6.5 删除,或者通过快照还原到单机伪分布安装前的环境。

node1-node4

mkdir /opt/apps

将 jdk-8u221-linux-x64.rpm 上传到 node1/opt/apps

将/opt/apps 下的 jdk.rpm scp 到 node2、node3、node4 的对应目录中

scp jdk-8u221-linux-x64.rpm node2:/opt/apps
scp jdk-8u221-linux-x64.rpm node3:/opt/apps
scp jdk-8u221-linux-x64.rpm node4:/opt/apps

在 node1、node2、node3、node4 上安装 jdk 并配置 profile 文件

rpm -ivh jdk-8u221-linux-x64.rpm

node1 上修改环境变量

vim /etc/profile
export JAVA_HOME=/usr/java/default
export PATH=$PATH:$JAVA_HOME/bin

将 node1 的/etc/profile 拷贝到 node2、node3、node4 上并执行. /etc/profile

scp /etc/profile node[234]:`pwd`

11.2.2.3 zookeeper 集群搭建

a) 将 zookeeper.tar.gz 上传到 node2

b) 解压到/opt

tar -zxvf zookeeper-3.4.6.tar.gz -C /opt

c) 配置环境变量:

export ZOOKEEPER_HOME=/opt/zookeeper-3.4.6
export PATH=$PATH:$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin

然后./etc/profile 让配置生效

最后将该文件 scp 到 node3 和 node4 上,并分别./etc/profile 让配置生效.

scp /etc/profile bk3:/etc/
scp /etc/profile bk4:/etc/

d) 到$ZOOKEEPER_PREFIX/conf 下

复制 zoo_sample.cfg 为 zoo.cfg

cp zoo_sample.cfg zoo.cfg

e) 编辑 zoo.cfg

添加如下行:

server.1=node2:2881:3881
server.2=node3:2881:3881
server.3=node4:2881:3881

修改

dataDir=/var/bjsxt/zookeeper/data

f) 创建/var/bjsxt/zookeeper/data 目录,并在该目录下放一个文件:myid

在 myid 中写下当前 zookeeper 的编号

mkdir -p /var/bjsxt/zookeeper/data
echo 1 > /var/bjsxt/zookeeper/data/myid

g)将配置好 zookeeper 拷贝到 node3、node4 上

scp -r zookeeper-3.4.6/ bk3:/opt/
scp -r zookeeper-3.4.6/ bk4:/opt/

h) 在 node3 和 node4 上分别创建/var/bjsxt/zookeeper/data 目录,并在该目录下放一个文件:myid

node3

mkdir -p /var/bjsxt/zookeeper/data
echo 2 > /var/bjsxt/zookeeper/data/myid

node4

mkdir -p /var/bjsxt/zookeeper/data
echo 3 > /var/bjsxt/zookeeper/data/myid

i) 分别启动 zookeeper

zkServer.sh start 启动 zk
zkServer.sh stop 停止 zk
zkServer.sh status 查看 zk 状态
zkServer.sh start|stop|status

j) 关闭 zookeeper

zkServer.sh stop

l) 连接 zookeeper

zkCli.sh  node2、node3、node4 都可以

m) 退出 zkCli.sh 命令

quit

11.2.2.4 hadoop  配置

在 一律在 node1  上操作,做完后 scp 到 到 node2 、node3 、node4

1. hadoop-env.sh 配置 JDK

export JAVA_HOME=/usr/java/default

2. 修改 slaves 指定 datanode 的位置

[root@node1 hadoop]# vim slaves
node2
node3
node4

3. core-site.xml

<configuration>
	<property>
		<name>fs.defaultFS</name>
		<value>hdfs://mycluster</value>
	</property>
	<property>
		<name>hadoop.tmp.dir</name>
		<value>/var/bjsxt/hadoop/ha</value>
	</property>
	<!-- 指定每个 zookeeper 服务器的位置和客户端端口号 -->
	<property>
		<name>ha.zookeeper.quorum</name>
		<value>node2:2181,node3:2181,node4:2181</value>
	</property>
</configuration>

4. hdfs-site.xml

<configuration>
	<!-- 指定副本的数量 -->
	<property>
		<name>dfs.replication</name>
		<value>2</value>
	</property>
	<!-- 解析参数 dfs.nameservices 值 hdfs://mycluster 的地址 -->
	<property>
		<name>dfs.nameservices</name>
		<value>mycluster</value>
	</property>
	<!-- mycluster 由以下两个 namenode 支撑 -->
	<property>
		<name>dfs.ha.namenodes.mycluster</name>
		<value>nn1,nn2</value>
	</property>
	<!-- 指定 nn1 地址和端口号 -->
	<property>
		<name>dfs.namenode.rpc-address.mycluster.nn1</name>
		<value>node1:8020</value>
	</property>
	<!-- 指定 nn2 地址和端口号 -->
	<property>
		<name>dfs.namenode.rpc-address.mycluster.nn2</name>
		<value>node2:8020</value>
	</property>
	<!-- 指定客户端查找 active 的 namenode 的策略:
	会给所有 namenode 发请求,以决定哪个是 active 的 -->
	<property>
		<name>dfs.client.failover.proxy.provider.mycluster</name>
		<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
	</property>
	<!-- 指定三台 journal node 服务器的地址 -->
	<property>
		<name>dfs.namenode.shared.edits.dir</name>
		<value>qjournal://node1:8485;node2:8485;node3:8485/mycluster</value>
	</property>
	<property>
		<name>dfs.journalnode.edits.dir</name>
		<value>/var/bjsxt/hadoop/ha/jnn</value>
	</property>
	<!-- 当 active nn 出现故障时,ssh 到对应的服务器,将 namenode 进程 kill 掉-->
	<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_dsa</value>
	</property>
	<!--启动 NN 故障自动切换 -->
	<property>
		<name>dfs.ha.automatic-failover.enabled</name>
		<value>true</value>
	</property>
</configuration>

5. 先同步配置文件到 node2、node3、node4

node1 上执行:

[root@node1 opt]# tar -zcvf hadoop-2.6.5.tar.gz hadoop-2.6.5/
[root@node1 opt]# scp hadoop-2.6.5.tar.gz node2:/opt/apps/
[root@node1 opt]# scp hadoop-2.6.5.tar.gz node3:/opt/apps/
[root@node1 opt]# scp hadoop-2.6.5.tar.gz node4:/opt/apps/

node2、node3、node4 分别执行解压:

tar -zxvf /opt/apps/hadoop-2.6.5.tar.gz -C /opt/

Hadoop 环境变量配置:

node1 上:

[root@node1 opt]# vim /etc/profile
export HADOOP_HOME=/opt/hadoop-2.6.5
export
PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

node2 上:

[root@node1 opt]# vim /etc/profile
export ZOOKEEPER_HOME=/opt/zookeeper-3.4.6
export HADOOP_HOME=/opt/hadoop-2.6.5
export
PATH=$PATH:$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
[root@node1 opt]#source /etc/profile
[root@node1 opt]# scp /etc/profile bk3:/etc/
[root@node1 opt]# scp /etc/profile bk4:/etc/

node3、node4 分别执行:

source /etc/profile

11.2.2.5 启动 ha 的 hdfs

a) 启动 zookeeper 集群, node2、node3、node4 分别执行:

zkServer.sh start

b) 在 node1\node2\node3 上启动三台 journalnode

hadoop-daemon.sh start journalnode

c) 选择 node1,格式化 HDFS

hdfs namenode -format

/var/bjsxt/hadoop/ha/dfs/name/current/目录下产生了 fsimage 文件格式化后,启动 namenode 进程

hadoop-daemon.sh start namenode

d) 在另一台 node2 上同步元数据

hdfs namenode -bootstrapStandby

出现以下提示:

=====================================================
About to bootstrap Standby ID nn2 from:
Nameservice ID: mycluster
Other Namenode ID: nn1
Other NN's HTTP address: http://node1:50070
Other NN's IPC address: node1/192.168.20.201:8020
Namespace ID: 178118551
Block pool ID: BP-1909026874-192.168.20.201-1577760263511
Cluster ID: CID-8105daf4-bdbb-40e8-a9d0-8d3f3867535b
Layout version: -60
isUpgradeFinalized: true
=====================================================

e) 初始化 zookeeper 上的内容 一定是在 namenode 节点(node1 或 node2)上。

执行格式命令之前在 node2-node4 任一节点上:

[root@node4 hadoop]# zkCli.sh
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]

只有默认的一个节点。

接下来在 node1 上执行:

[root@node1 ~]# hdfs zkfc -formatZK

然后在 node4 上接着执行:

[zk: localhost:2181(CONNECTED) 1] ls /
[zookeeper, hadoop-ha]
[zk: localhost:2181(CONNECTED) 2] ls /hadoop-ha
[mycluster]
[zk: localhost:2181(CONNECTED) 3] ls /hadoop-ha/mycluster
[]

f) 启动 hadoop 集群,可在 node1 到 node4 这四台服务器上任意位置执行

[root@node1 ~]# start-dfs.sh

node4 上:

[zk: localhost:2181(CONNECTED) 5] ls /hadoop-ha/mycluster
[ActiveBreadCrumb, ActiveStandbyElectorLock]
[zk: localhost:2181(CONNECTED) 6] get
/hadoop-ha/mycluster/ActiveStandbyElectorLock
myclusternn2node2 �>(�>
cZxid = 0x500000007
ctime = Tue Dec 31 11:04:24 CST 2019
mZxid = 0x500000007
mtime = Tue Dec 31 11:04:24 CST 2019
pZxid = 0x500000007
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x26f599f159b0000
dataLength = 27
numChildren = 0

node2 占用着锁,它的状态是 active 的

node1 为 standby

将 node2 上 namenode 进程 kill 掉:

[root@node2 hadoop]# jps
1970 Jps
1158 QuorumPeerMain
1335 JournalNode
1546 DataNode
1660 DFSZKFailoverController
1871 NameNode
[root@node2 hadoop]# kill -9 1871
[root@node2 hadoop]# jps
1158 QuorumPeerMain
1335 JournalNode
1546 DataNode
1980 Jps
1660 DFSZKFailoverController

node4 上继续:

[zk: localhost:2181(CONNECTED) 10] get
/hadoop-ha/mycluster/ActiveStandbyElectorLock
myclusternn2node1 �>(�>
cZxid = 0x50000000b

node2 访问不了,node1 变为 active。

node2 上再次启动 namenode:

[root@node2 hadoop]# hadoop-daemon.sh start namenode

node2 依然为 standby。变为备机。

node1 上停掉 zkfc 执行:

[root@node1 hadoop]# hadoop-daemon.sh stop zkfc

[root@node1 hadoop]# jps
1158 QuorumPeerMain
1335 JournalNode
1546 DataNode
2012 NameNode
1660 DFSZKFailoverController
2111 Jps
[root@node1 hadoop]# kill -9 1660
[root@node1 hadoop]# jps
1158 QuorumPeerMain
1335 JournalNode
2136 Jps
1546 DataNode
2012 NameNode

node2 变为 active 状态

stop-dfs.sh 停止 hadoop 服务。

node1 上编写 zk、hdfs 启动脚本

[root@node1 ~]# vim starthdfs.sh
#!/bin/bash
for node in node2 node3 node4
54
do
ssh $node "source /etc/profile;zkServer.sh start"
done
sleep 1
start-dfs.sh
echo "-------node1 jps-----"
jps
for nd in node2 node3 node4
do
echo "-------$nd jps-----"
ssh $nd "source /etc/profile;jps"
done
:wq
[root@node1 ~]# chmod +x starthdfs.sh
[root@node1 ~]# cp starthdfs.sh stopdfs.sh
[root@node1 ~]# vim stopdfs.sh
#!/bin/bash
stop-dfs.sh
sleep 1
for node in node2 node3 node4
do
ssh $node "source /etc/profile;zkServer.sh stop"
done
echo "-------node1 jps-----"
jps
for nd in node2 node3 node4
do
echo "-------$nd jps-----"
ssh $nd "source /etc/profile;jps"
done
:wq

如果格式化之后,启动:

启动三台 zk

随意节点:start-dfs.s

hadoop-daemon.sh stop namenode

hadoop-daemon.sh stop zkfc

11.2.2.6 zookeeper 操作

在 node2 或者 node3 或者 node4 上运行

zkCli.sh

ls /hadoop-ha/mycluster 查看临时文件

get /hadoop-ha/mycluster/ActiveStandbyElectorLock 查看临时文件的内容

退出 zkCli.sh

quit

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

plenilune-望月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值