namenode 的 HA 主要分为共享 editlog 机制和 ZKFC 对 namenode 状态的控制。
- 集群中存在多个 namenode ,这些 namenode 都有状态,处于 active 或者 standby 状态
- 各个 namenode 之间通过共享文件系统存储日志文件。active master 将信息写入共享存储系统,而 standby master 则读取该信息以保持与 active master 的同步,从而减少切换时间
- datanode 同时需要向各个 namenode 发送数据快处理报告(通过心跳报告自身拥有的数据块)
- 每一个 namenode 运行着一个轻量级的故障转移控制器 ZKFC,用于监视和控制 NN 进程,每个 ZKFC 都会定期 ping 与自己在同一台主机的 namenode,如果 namenode 能正常回复那么就认为这个 namenode 是正常的,否则就认为他是故障的。随后进行主备切换
- 基于 Zookeeper 实现的切换控制器 ZKFC 进程,主要由三个核心组件构成:ActivestandbyElector 、Healthmonitor 和 ZKFailoverController。
- ZKFailoverController: 是HealthMontior和ActiveStandbyElector的母体,执行具体的切换操作
- HealthMonitor: 监控NameNode健康状态,若状态异常会触发回调ZKFailoverController进行自动主备切换
- ActiveStandbyElector: 通知ZK执行主备选举,若ZK完成变更,会回调ZKFailoverController相应方法进行主备状态切换
- 在进行状态切换时,转换为 active 状态的 NN 会向之前 active 的 NN 发送一条命令来终止进程,Hadoop 对外提供了两种方法来实现此过程,分别时 sshfence 和 shellfence,其中 sshfence(缺省方法)是通过 ssh 登陆目标 master 节点,使用 kill 命令将进程杀死(通过 tcp 端口号定位进程 pid),shellfence 执行自定义脚本
补充:
https://blog.csdn.net/wz_txwy/article/details/99888654
ActivestandbyElector 为了实现 fencing(隔离,防止脑裂),会在成功创建 Zookeeper 临时节点 hadoop-ha/${dfs.nameservices}/ActivestandbyElectorLock
之后,创建另一个路径为 hadoop-ha/${dfs.nameservices}/ActiveBreadCrumb
的持久节点,这个节点里面存储了这个 Active NN 的地址信息。Active NN 在正常情况下关闭 Zookeeper Session 的时候,临时节点 hadoop-ha/${dfs.nameservices}/ActivestandbyElectorLock
也会随着删除,此处持久节点 hadoop-ha/${dfs.nameservices}/ActiveBreadCrumb
也会被主动删除。但是如果是在异常情况下 Zookeeper Session 关闭(例如 NN 正在 GC,造成心跳超时,临时节点自动被删除,但持久节点会被保存下来),这时新的 Active NN 会注意到这个遗留下来的持久节点,它首先会尝试将前面的节点转为 Stanby 状态,如果失败就会对其进行默认 fencing 操作,kill 进程
只有在成功 fencing 之后,当选节点的 ActivestandbyElector 才会回调 ZKFailoverController 将自己转为 active 状态,之前只是获取到了 ActivestandbyElectorLock 锁,并不算真正当选