Hadoop学习笔记(五)HA
一、简介
high availability(HA, 高可用)。之前我们的NameNode只有一个节点,这就容易造成单点故障,即NameNode一旦出现问题,整个集群将不可用。因此HA就显得重要了。它的特点:
- 拥有两个名称节点,分别处于active(激活态)、standby(待命)。
- 与客户端进行交互的只有处于active,standby不参与。
- 两个节点都和 Journal Node(JN,存放编辑日志的节点)守护进程构成组的进行通信。
- 同一时刻,只能有一个处于active。
- 脑裂:即两个节点都是激活态(这是非常严重的)。为了防止脑裂,JNs只允许同一时刻只有一个节点向其写数据。容灾发生的时候,成为active的节点的namenode接管向jn写入的工作。
二、硬件资源
两个名称节点硬件配置要相同
JN节点:轻量级进程,至少3个节点,允许挂掉的节点数为(n - 2 )/ 2。
note:因为有了JN,不再需要运行辅助名称节点。
三、部署HA
3.1 前期准备
因为需要两个节点作为NameNode(而目前的规划是:名称节点 s201,数据节点 s202,s203,s204,辅助名称节点s206),我们知道在HA下,是不需要辅助名称节点的。因此,将s205作为另一台NameNode。
目前只有s201可以SSH到其余所有节点,而s205同样也需要。
s205生成SSH
Code$ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
把公钥发送到s201
Code[wbw@s205 /home/wbw/.ssh]$scp ~/.ssh/id_rsa.pub wbw@s201:/home/wbw/.ssh/id_rsa.pub.s205
在s201上将公钥分发到所有节点上,并追加到列表
Code[wbw@s201 /home/wbw/.ssh]$xsync.sh id_rsa.pub.s205
[wbw@s201 /home/wbw/.ssh]$xcall.sh "cat /home/wbw/.ssh/id_rsa.pub.s205 >> /home/wbw/.ssh/authorized_keys"验证s201和s205是否可以SSH所有节点
记得把s201上的黑白名单也拷过去
Code[wbw@s201 /soft/hadoop/etc]$scp dfs.hosts wbw@s205:/soft/hadoop/etc/dfs.hosts
[wbw@s201 /soft/hadoop/etc]$scp dfs.hosts.exclude wbw@s205:/soft/hadoop/etc/dfs.hosts.exclude
3.2 配置XML(HDFS)
在s201上,复制一份完全分布式full的配置,取名为ha
Code[wbw@s201 /soft/hadoop/etc]$cp -r full ha
在ha中修改hdfs-site.xml配置文件信息(主要说明谁是NN谁是JN)
配置nameservice
xml<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>dfs.ha.namenodes.[nameservice ID]
xml<!-- myucluster下的名称节点两个id(只能有2个) -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>dfs.namenode.rpc-address.[nameservice ID].[name node ID]
xml<!-- 配置每个nn的rpc地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>s201:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>s205:8020</value>
</property>dfs.namenode.http-address.[nameservice ID].[name node ID]
xml<!-- 配置每个nn的webui端口 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>s201:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>s205:9870</value>
</property>dfs.namenode.shared.edits.dir
xml<!-- 名称节点共享编辑目录,即JN节点 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://s202:8485;s203:8485;s204:8485/mycluster</value>
</property>dfs.client.failover.proxy.provider.[nameservice ID]
xml<!-- java类,client使用它判断哪个节点是激活态 -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>dfs.ha.fencing.methods
xml<!-- 脚本列表或者java类,在容灾保护激活态的nn. -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>
sshfence
shell(/bin/true)
</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/wbw/.ssh/id_rsa</value>
</property>dfs.journalnode.edits.dir
xml<!-- 配置JN存放edit的本地路径 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/wbw/hadoop/journal</value>
</property>
在ha中修改core-site.xml配置文件信息(主要说明谁是NN谁是JN)
配置hdfs文件系统名称服务
xml<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
最后将ha分发到所有节点上,并且把hadoop连接到ha
Code[wbw@s201 /soft/hadoop/etc]$xsync.sh ha
[wbw@s201 /soft/hadoop/etc]$xcall.sh "ln -sfT /soft/hadoop/etc/ha /soft/hadoop/etc/hadoop"
查看是否成功
[wbw@s201 /soft/hadoop/etc]$xcall.sh "ls -al /soft/hadoop/etc/"
3.3 数据迁移
停掉所有Hadoop进程
在JN节点(s202,s203,s204)上分别启动JN进程
Code[wbw@s202 /home/wbw]$hadoop-daemon.sh start journalnode
[wbw@s203 /home/wbw]$hadoop-daemon.sh start journalnode
[wbw@s204 /home/wbw]$hadoop-daemon.sh start journalnode启动jn之后,在两个NN之间进行disk元数据同步
如果是全新集群,先format文件系统,只需要在一个nn上执行
Codehadoop namenode -format
如果之前有数据,但是不想要了,想要一个全新的。那么就直接删除所有节点的日志和本地数据。然后执行该命令。(即全新,保证两个NN内容都是空的)
如果将非HA集群转换成HA集群,复制原NameNode的metadata到另一个nn
到s201将元数据信息复制到s205
Code[wbw@s201 /home/wbw]$scp -r /home/wbw/hadoop/dfs wbw@s205:/home/wbw/hadoop/
在新的nn(未格式化的nn)【这里为s205】上运行一下命令,实现待命状态引导。
Code# 需要s201的namenode为启动状态,提示是否格式化,选择N
[wbw@s201 /home/wbw]$hadoop-daemon.sh start namenode
[wbw@s205 /home/wbw]$hdfs namenode -bootstrapStandby在一个NN上执行以下命令,完成edit日志到jn节点的传输。
Code[wbw@s201 /home/wbw]$hdfs namenode -initializeSharedEdits
# 查看s202,s203,s204是否有edit数据.
启动所有节点
在s201
Code$>hadoop-daemon.sh start namenode //启动名称节点
$>hadoop-daemons.sh start datanode //启动所有数据节点在s205
Code$>hadoop-daemon.sh start namenode //启动名称节点
查看web-UI(如果zookeeper没有配置,那么s201,s205将都出现standby)
四、管理命令
假如你没有配置zookeeper,这时候如果查看WEB-UI发现2个都是standby状态,说明不能自动切换现在,还需要ZK才可以自动。现在只能手动切换
4.1 切换激活态
$>hdfs haadmin -transitionToActive nn1
4.2 切换待命态
$>hdfs haadmin -transitionToStandby nn1
4.3 强行激活
会出现2个active很危险!!!
$>hdfs haadmin -transitionToActive –forceactive nn2
4.4 模拟容灾
模拟容灾演示,从nn1切换到nn2
$>hdfs haadmin -failover nn1 nn2
五、HA自动容灾
如果要实现自动容灾,那么请移步”ZooKeeper学习笔记“文章,先给集群装上zookeeper然后进行相应配置。
【NOTE】如果你的zookeeper不够干净,即使用操作过。那么先进行清理操作:删除zookeeper数据目录中的版本信息verson目录。然后启动ZK集群。
# 之前有对集群操作过,所以进行数据清理 |
5.1 介绍
自动容灾引入两个组件,zk quarum + zk容灾控制器(ZKFC)。
运行NN的主机还要运行ZKFC进程,主要负责:
1. 健康监控
2. session管理
3. 选举
5.2 HDFS自动容灾
停掉所有进程
修改hdfs-site.xml
xml[wbw@s201 /soft/hadoop/etc/ha]$vi hdfs-site.xml
# 添加如下内容
<!-- 启动自动容灾 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>修改core-site.xml(我的zk集群规划为s201,s202,s203)
xml# 添加新内容
<!-- 指定zk连接地址,s生产环境一般用IP -->
<property>
<name>ha.zookeeper.quorum</name>
<value>s201:2181,s202:2181,s203:2181</value>
</property>分发以上两个文件到所有节点
登录其中一台NN(s201),在ZK中初始化HA状态。
Code$hdfs zkfc -formatZK
启动hdfs进程
Code$start-dfs.sh
Starting namenodes on [s201 s205]
Starting datanodes
Starting journal nodes [s202 s204 s203]
Starting ZK Failover Controllers on NN hosts [s201 s205]查看zookeeper会发现,多了以下内容
Code/hadoop-ha
/hadoop-ha/mycluster
/hadoop-ha/mycluster/ActiveBreadCrumb
/hadoop-ha/mycluster/ActiveStandbyElectorLock查看WEB-UI,可以看到可以自动切换成active了
测试自动容灾(当前active在s201,则kill -9 掉s201的nn)
可以看到可以实现自动容灾了。
5.3 RM自动容灾
resourcemanager的自动容灾也是需要zk来实现
配置yarn-site.xml
xml[wbw@s201 /soft/hadoop/etc/ha]$vi yarn-site.xml
# 添加如下内容
<!-- 开启yarn的HA -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 配置名字ID -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster1</value>
</property>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 配置RM节点地址 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>s201</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>s205</value>
</property>
<!-- 配置RM,WEB-UI端口 -->
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>s201:8088</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>s205:8088</value>
</property>
<!-- 配置ZK集群 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>s201:2181,s202:2181,s203:2181</value>
</property>分发到所有节点
启动yarn
Code$start-yarn.sh
Starting resourcemanagers on [ s201 s205]
Starting nodemanagers管理命令查看
Code[wbw@s201 /soft/hadoop/etc/ha]$yarn rmadmin -getServiceState rm1
standby
[wbw@s201 /soft/hadoop/etc/ha]$yarn rmadmin -getServiceState rm2
activeWEB-UI查看(IP:8088 –> Aboute)
模拟容灾
首先检查JPS是否2个节点上的RM进程都开启,如果没有,则进入相应节点上启动。
Code# 启动单个RM节点
$yarn-daemon.sh start resourcemanager杀掉active的RM进程(这里是s205)
查看状态
Code[wbw@s201 /soft/hadoop/etc/ha]$yarn rmadmin -getServiceState rm1
active自动容灾成功。
5.4 集群总结
自此,应该可以说所有的相关设置都已经完成了。现在来总结下:
[wbw@s201 /soft/hadoop/etc/ha]$xcall.sh jps |
集群规划情况
HDFS
- NameNode:s201、s205
- DateNode:s202、s203、s204
Yarn
- ResourceManager:s201、s205
- NodeManager:s202、s203、s204
ZooKeeper
- DFSZKFailoverController(ZKFC):s201、s205
- QuorumPeerMain:s201、s202、s203
HA
- JournalNode:s202、s203、s204
启动集群
[wbw@s201 /home/wbw]$zkServer.sh start |
关闭集群
[wbw@s201 /home/wbw]$stop-yarn.sh |