HA故障切换功能测试

背景

一、NameNode 保存了整个 HDFS 的元数据信息,一旦 NameNode 挂掉,整个 HDFS 就无法访问,为了解决namanode单点的问题,hadoop2.X通过配置active/stanby两个namenode,进而实现namenode的热备。 二、ResourceManager 可以启动多台,只有其中一台是 active 状态的,其他都处于待命状态。这台 active 状态的 ResourceManager 执行的时候会向 ZooKeeper 集群写入它的状态,当它故障的时候这些 RM 首先选举出另外一台 leader 变为 active 状态,然后从 ZooKeeper 集群加载 ResourceManager 的状态。在转移的过程中它不接收新的 Job,转移完成后才接收新 Job。

基础信息

hadoop版本 3.3.1 内网 网络信息服务器信息

IP
操作系统
CPU
内存 磁盘空间 顺序读 顺序写

10.241.80.131
CentOS Linux release 7.6.1810
8

16

200G

235MB/s

107MB/s

10.241.80.147
CentOS Linux release 7.6.1810
8

16

200G

237MB/s

102MB/s

10.241.80.148
CentOS Linux release 7.6.1810
8

16

200G

283MB/s

113MB/s
1.读写测试命令如下: 顺序写: time dd if=/dev/zero of=/data/ddtest bs=1k count=10000000 conv=fdatasync 顺序读: time dd if=/data/ddtest of=/dev/null bs=1k count=10000000 status=progress

一、namenode主备切换

主备切换机制

要完成HA,除了元数据同步外,还得有一个完备的主备切换机制,Hadoop的主备选举依赖于ZooKeeper 主备切换状态图:

ha故障切换 - 图1

整个切换过程是由ZKFC来控制的,具体又可分为HealthMonitor、ZKFailoverController和ActiveStandbyElector三个组件。 1、ZKFailoverController: 是HealthMontior和ActiveStandbyElector的母体,执行具体的切换操作 2、HealthMonitor: 监控NameNode健康状态,若状态异常会触发回调ZKFailoverController进行自动主备切换 3、ActiveStandbyElector: 通知ZK执行主备选举,若ZK完成变更,会回调ZKFailoverController相应方法进行主备状态切换 在故障切换期间,ZooKeeper主要是发挥什么作用呢,有以下几点: 1、失败保护:集群中每一个NameNode都会在ZooKeeper维护一个持久的session,机器一旦挂掉,session就会过期,故障迁移就会触发 2、Active NameNode选择:ZooKeeper有一个选择ActiveNN的机制,一旦现有的ANN宕机,其他NameNode可以向ZooKeeper申请排他成为下一个Active节点 3、防脑裂: ZK本身是强一致和高可用的,可以用它来保证同一时刻只有一个活动节点

Hadoop 2.x元数据

Hadoop的元数据主要作用是维护HDFS文件系统中文件和目录相关信息。元数据的存储形式主要有3类:内存镜像、磁盘镜像(FSImage)、日志(EditLog)。在Namenode启动时,会加载磁盘镜像到内存中以进行元数据的管理,存储在NameNode内存;磁盘镜像是某一时刻HDFS的元数据信息的快照,包含所有相关Datanode节点文件块映射关系和命名空间(Namespace)信息,存储在NameNode本地文件系统;日志文件记录client发起的每一次操作信息,即保存所有对文件系统的修改操作,用于定期和磁盘镜像合并成最新镜像,保证NameNode元数据信息的完整,存储在NameNode本地和共享存储系统(QJM)中。 如下所示为NameNode本地的EditLog和FSImage文件格式,EditLog文件有两种状态: inprocess和finalized, inprocess表示正在写的日志文件,文件名形式:editsinprocess[start-txid],finalized表示已经写完的日志文件,文件名形式:edits[start-txid][end-txid]; FSImage文件也有两种状态, finalized和checkpoint, finalized表示已经持久化磁盘的文件,文件名形式: fsimage_[end-txid], checkpoint表示合并中的fsimage, 2.x版本checkpoint过程在Standby Namenode(SNN)上进行,SNN会定期将本地FSImage和从QJM上拉回的ANN的EditLog进行合并,合并完后再通过RPC传回ANN

ha故障切换 - 图2

QJM 写过程

NameNode会把EditLog同时写到本地和JournalNode。写本地由配置中参数dfs.namenode.name.dir控制,写JN由参数dfs.namenode.shared.edits.dir控制,在写EditLog时会由两个不同的输出流来控制日志的写过程,分别为:EditLogFileOutputStream(本地输出流)和QuorumOutputStream(JN输出流)。写EditLog也不是直接写到磁盘中,为保证高吞吐,NameNode会分别为EditLogFileOutputStream和QuorumOutputStream定义两个同等大小的Buffer,大小大概是512KB,一个写Buffer(buffCurrent),一个同步Buffer(buffReady),这样可以一边写一边同步,所以EditLog是一个异步写过程,同时也是一个批量同步的过程,避免每写一笔就同步一次日志

隔离

在ANN每次同步EditLog到JN时,先要保证不会有两个NN同时向JN同步日志。这个隔离是怎么做的。这里面涉及一个很重要的概念Epoch Numbers,很多分布式系统都会用到。Epoch有如下几个特性: 1、当NN成为活动结点时,其会被赋予一个EpochNumber 2、每个EpochNumber是惟一的,不会有相同的EpochNumber出现 3、EpochNumber有严格顺序保证,每次NN切换后其EpochNumber都会自增1,后面生成的EpochNumber都会大于前面的EpochNumber QJM是怎么保证上面特性的呢,主要有以下几点 这样就能保证主备NN发生切换时,就算同时向JN同步日志,也能保证日志不会写乱,因为发生切换后,原ANN的EpochNumber肯定是小于新ANN的EpochNumber,所以原ANN向JN的发起的所有同步请求都会拒绝,实现隔离功能,防止了脑裂。 1、在对EditLog作任何修改前,QuorumJournalManager(NameNode上)必须被赋予一个EpochNumber 2、QJM把自己的EpochNumber通过newEpoch(N)的方式发送给所有JN结点 3、 当JN收到newEpoch请求后,会把QJM的EpochNumber保存到一个lastPromisedEpoch变量中并持久化到本地磁盘 4、 ANN同步日志到JN的任何RPC请求(如logEdits(),startLogSegment()等),都必须包含ANN的EpochNumber 5、JN在收到RPC请求后,会将之与lastPromisedEpoch对比,如果请求的EpochNumber小于lastPromisedEpoch,将会拒绝同步请求,反之,会接受同步请求并将请求的EpochNumber保存在lastPromisedEpoch

场景一

activenamenode宕机自动切换 切换前检查: 131为active

ha故障切换 - 图3

147为standby

ha故障切换 - 图4

故障模拟: 手动把131的activenamenode停掉

ha故障切换 - 图5

查询147namenode状态

ha故障切换 - 图6

此时ANN已经切换完成 具体切换日志:

ha故障切换 - 图7

场景二

ZKFC崩溃自动切换 切换前检查: 131为active

ha故障切换 - 图8

147为standby

ha故障切换 - 图9

故障模拟: 手动把131(active)上的zkfc停掉

ha故障切换 - 图10

查询namenode状态

ha故障切换 - 图11

此时131上的namenode已经变为了standby,147上的NN变为了active

场景三

zookeeper崩溃 切换前检查:

ha故障切换 - 图12

故障模拟: 1、停掉一台zk,再把activenamenode(131)停掉

ha故障切换 - 图13

查询namenode状态,147上已经切换为active

ha故障切换 - 图14

2、停掉两台zk,再把activenamenode(147)停掉 查询namenode状态,131上已经不能切换为active了,所以zk要保证N/2+1可用

ha故障切换 - 图15

场景四

上传大文件,发生主备切换,文件能否继续上传&&发生故障切换时,客户端连接现象 测试前检查: 147为active,131为standby

ha故障切换 - 图16

上传大文件之后手动停掉147上的activenamenode:

ha故障切换 - 图17

ha故障切换 - 图18

对比上传前后大小(一致):

ha故障切换 - 图19

ha故障切换 - 图20

把安装包拉到本地,查看是否有损坏: 对比MD5(一致):

ha故障切换 - 图21

ha故障切换 - 图22

查看解压是否正常:

ha故障切换 - 图23

ha故障切换 - 图24

测试过程遇到问题: ansible部署hadoop集群,当activenamenode故障时,不发生切换,需修改如下参数:

ha故障切换 - 图25

二、YARN-RM主备切换

切换前检查: 148为active,147为standby ha故障切换 - 图26 故障模拟: 把131上RM停掉

ha故障切换 - 图27

检查RM状态(切换过程很慢,大概持续几分钟):

ha故障切换 - 图28

此时147上的standby已经变为了active 测试结论 当activenamenode出现问题时,会自动发生故障切换,保证集群的可用性,并且在故障切换的过程中写入的数据不会丢失和损坏。 当activeresourcemanager发生故障时,会自动发生故障切换,但是在故障切换的过程中,resourcemanager不会接受新的任务,待切换完成后才会处理新的任务。