普通版2.x组成及基本功能
相较于普通版本高可用架构作出以下调整
- 去掉了secondaryNamenode,并增加了一个新的namenode与状态(active和standby)
- 增加了zookeeper与主备切换控制器failoverController(下文均称为zkfc)和健康监控health monitor机制
组成详解
- 我的上一篇分布式文件系统有基本功能的图解本篇不详细讲,挑高可用重点讲
- namenode: 两台互备,一台active为主namenode,对外读写任务调度,综合机架感知,网络拓扑,副本机制,告知client去哪个datanode进行读或者写
- zkfc主备切换器:及时检测namenode的健康状态,activenamenode故障时自动进行主备选举和切换
- zookeeper集群:为主备切换控制器提供主备选举支持可以看我之前的zookeeper功能和选举模式,简单来说就是利用watch配合会话临时目录完成抢锁,实现选举
- 共享存储系统:保存namenode在运行过程产生的元数据,同步到备份节点。实现namenode的高可用
- datanode
主备切换实现
- zkfc
启动时会创建 healthMonitor和activestandbyelecor两个主要的内部组件,同时注册回调
- HealthMonitor:检测namenode健康状态,宕机时会回调zkfc对应方法进行主备选举
- ActiveStandByElector:主要负责完成自动的主备选举,并且回调zkfc的方法完成namenode主备状态切换
步骤
- 0.zkfc初始化时创建healthMonitor
- 1.healthMonitor初始化完成之后会启动内部的线程定时调用对应的namenode中HAServiceProtocol RPC接口方法,进行健康状态检测
- 2.检测到健康状态变化,会回调zkfc注册对应方法处理
- 3.判断需要主备切换,使用acitvestandbyelector进行自动的主备选举
- 4.选举完成通知新的主namenode和备namenode
- 5.zkfc调用对应namenode的HAServiceProtocol RPC 接口的方法将 NameNode 转换为 Active 状态或 Standby 状态。
HealthMonitor,检测的主要部分
主要任务
- 1.检测namenode的两类状态 healthMonitor.state和HAServiceStatus。state反应namenode节点健康状况,主要是磁盘存储资源是否充足,异常状态有not_response,unhealthy,failed。
HAServiceStatus,检测中辅助作用
- 反应namenode的HA状态
ActiveStandbyElector主备选举
- 利用zookeeper的写一致性和临时节点机制
- 1.创建锁节点,创建成功的namenode会切换到active,失败的为备选并且由ActiveStandbyElector回调zkfc将其转为standbyzookeeper功能和选举模式
- 2.注册watcher监听,不管是否抢锁成功都会注册一个watch来监听节点状态变化事件,ActiveStandbyElector主要关注节点的nodeDelete
3.自动触发主备选举,
- 3.1Active NameNode 对应的 HealthMonitor 检测到namenode状态异常,zkfc会主动删除在当前zookeeper上建立的锁节点,而standby状态的namenode的ActiveStandbyElector注册的监听器就会收到这个节点的nodedel事件,紧接着马上再次进入到创建锁的过程,创建成功,standby便转为active
- 3.2active的namenode整个机器宕机由于临时节点机制,锁节点被自动删除,也会自动进行一次主备切换
4.防止脑裂
- zookeeper客户端负载过高或正在进行jvm full gc导致与zookeeper服务端心跳不能正常发出多次国有被判定为会话过期,假设namenode1对应zkfc假死,zookeeper认为其挂掉切换主机为namenode2,此时namenode1的zkfc随着负载下降恢复正常,但网络延迟和cpu线程调度不确定导致namenode1可能会仍认为自己是active。namenode1与namenode2此时都可以对外提供服务对于一致性要求高的系统来说是灾难性的
- ActiveStandbyElector 采用了fencing将旧节点隔离,不仅用了临时的锁节点(ActiveStandbyElectorLock),并且还生成一个持久节点(ActiveBreadCrumb),保存当前acitvenamenode地址信息,正常关闭zookeepersession时该持久节点是会删除的,但某次选举成功后如果新的activenamenode发现旧的持久节点仍然存在会回调zkfc方法对旧的namenode进行fencing
4.1其他参考方案
- 冗余心跳线,多条心跳线尽量减少裂脑事件
- 智能磁盘锁,正在服务的一方,检测不到对方的心跳时启动磁盘锁
- 仲裁机制:心跳断开时,ping网管ip,不通主动放弃竞争自动重启
zkfc实现
- zkfc在创建healthMonitor和acitveStandbyElector的同时,会向healthMonitor和activeStandbyElector注册相应的回调,处理则主要靠这些回调
- 如果ActiveStandbyElector选主成功,对应的namenode成为主namenode,ActiveStandbyElector回调zkfc的becomeActive,而becomeActive会调用对应namenode的HAserviceprotocol rpc接口的transitiontoacive方法将namenode转为active
- 选主失败,变为备namenode,activestandbyelector会回调zkfc的becomestandby调用对应namenode的HAServiceProtocol RPC接口的transitiontostandby方法将对应namenode变为standby
选主成功却发现上一个active留下来的持久化节点,则先调用zkfc注册的fenceOldActive尝试隔离旧的active namenode,过程为以下几部分
- 1.尝试调用旧active namenode的HAServiceProtocol RPC接口的transittionToStandby方法,
2.失败的话执行配置文件中的隔离措施
- 2.1sshfence 通过ssh登录到目标机器执行fuser干掉对应进程
- 2.2shellfence 执行一个用户自定义的shell脚本将对应的进程隔离
- 3.只有在成功进行fencing后才会再回调zkfc的becomeActive方法将对应的namenode切换为active对外提供服务
NameNode的共享存储实现
元数据存储,namenode启动恢复
- hdfs原理读写部分简单说明就是namenode在执行hdfs客户端提交的操作时会把这些操作记录在edits中,一定条件下,满64m或一小时或重启会新建并切换到一个edits记录,并且namenode会定期对edits进行合并生成fsimage,与1.x不同,原本由secondarynamenode完成此项任务,
- namenode启动时需要将fsimage文件加载到内存后再加载edits恢复到关闭前状态
- QJM共享存储参考QJM数据同步
常见问题
- zookeeper过于敏感导致无谓的namenode切换,session-timeout默认值调高
- 羊群效应,大量节点监控一个节点,变化后需要通知的节点很多导致性能下降,根据业务调整
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。