HDFS HA相关的几个问题和示例场景

问题

  1. 何时会触发主备选举
    当active nn的HealthMonitor检测到active状态为_SERVICE_UNHEALTHY_和_SERVICE_NOT_RESPONDING_时,active的ActiveStandbyElector会quitElection,quitElection就是关闭zk连接(zk关闭连接之后,相应的watcher也失去作用),ZKFailoverController会主动删除当前在Zookeeper上建立的临时节点/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock,此时active的zk已经关闭连接,watcher已无法监听到DeleteNode事件,standby上的watcher则可以监听到DeleteNode事件,会马上再次进入到创建/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock节点的流程,如果创建成功,这个本来处于Standby状态的NameNode 就选举为主NameNode并随后开始切换为Active状态。

  2. active所在的主机宕机(ActiveNN断电,网络异常,负载过高或者机器出现异常无法连接),standby能否切换成功,怎么配置
    active宕机,active上的zkfc也退出,导致与zk的连接关闭,临时节点ActiveStandbyElectorLock被删除,但ActiveBreadCrumb没有删除,standby上的ActiveStandbyElector检测到节点ActiveStandbyElectorLock被删除,进行抢锁,去创建节点ActiveStandbyElectorLock,创建成功之后,进行状态切换,调用becomeActive,因为ActiveBreadCrumb没有被删除,为了防止脑裂会调用fenceOldActive去fence,如果fence成功则进行状态的写入,状态切换成功。由此可见fence的成决定了切换是否成功,fence方法有两个,一个是sshfence,另一个是shell。当active宕机,则ssh不通,sshfence会fence失败,也就是说如果只配置了sshfence方法,则无法切换成功当active宕机,想切换成功需要配置shell方法,shell方法可以说是来弥补active宕机的所以在配置fence method的时候最好配置两个方法

  3. active发生异常,active上的zkfc会不会进行fence
    zkfc进行fence的时候是在拿到createLock之后,nn进行状态转换时才进行fence。active发生异常,其上的zkfc不会进行fence,因为healthmonitor检测到异常之后,会让其退出选举,也就是关闭zk连接,zk连接关闭之后,注册的watcher也消失,也就无法监听到节点被删除,也就不会去抢锁,更不会去fence。

  4. SSHFence是从standby ssh到active进行fence,那ShellFence是怎么搞的?
    在哪执行,谁调用的,怎么进行kill掉active
    shell fence是怎么到原active机器上执行的?
    shell fence 不会到原active上执行activekill掉,shell可以是一个空命令使其单纯的正常退出,然后standby会进行状态转换。但是我疑惑的是shell只是将standby进行的状态转换,但原active呢?原active检测到异常,退出选举关闭了zk连接,只有HM在不断的检测nn的状态,当检测到healthy之后,重新建立zk连接,然后watcher捕获到连接事件,调用monitorActiveStatus进行状态的检查进行变换,此时原active变为standby但是假如原active一直是不健康的呢?那么原active是怎么进行状态转换的

  5. fence method需要怎么配置,如果需要配置两个方法,那为什么不只配置shell menthod

  6. 一般导致NameNode切换的原因
    nn不健康(没有磁盘空间),rpc没有响应(callqueue占满),
    随着集群规模的变大和任务量变多,NameNode的压力会越来越大,一些默认参数已经不能满足集群的日常需求,除此之外,异常的Job在短时间内创建和删除大量文件引起NN节点频繁更新内存的数据结构从而导致RPC的处理时间变长,CallQueue里面的RpcCall堆积,甚至严重的情况下打满CallQueue,导致NameNode响应变慢,甚至无响应,ZKFC的HealthMonitor监控自己的NN异常时,则会断开与ZooKeeper的链接,从而释放锁,另外一个NN上的ZKFC进行抢锁进行Standby到Active状态的切换。这是一般引起的切换的流程。

  7. active发生异常,并且active和standby无法正常ssh,fence methods设置的为ssh 和 shell,此时能否切换成功
    HealthMonitor检查到active不正常,放弃选举,断开zk连接,临时节点被删除,standby进行选举,创建临时节点成功,准备becomeActive,此时发现ActiveBreadCrumb上存储的信息和当前节点不一致,进行fence,FailoverController没有gracefully fence成功,进行NodeFence.fence,首先选用ssh,发现ssh不通,再选择shell,shell返回正常值(shell中没有任何逻辑直接返回正常值),standby转换状态为active成功,此时原active节点的状态是什么?是不是两个节点都是active,出现脑裂?,不会出现脑裂,zfkc会在进行状态检查时将原active变成standby

示例场景

  • ActiveNN产生JVM crash
    一旦这种情况发生,HealthMonitor在调用monitorHealth()将失效。然后HM将向ZKFC调用enterState(SERVICE_NOT_RESPONDING),本地ZKFC将退出Election,另外一个ZKFC获取active lock,执行fencing,变成active。

  • ActiveNN JVM freeze
    如果JVM freeze了但是没有crash掉,这与上面情况一样,monitorHealth会由于timeout而引发上述过程。FUTURE-WORK:使用JVMTI来判断NN是否在进行gc,如此可以使用另一个timeout来为gc进行failover。

  • ActiveNN machine crash
    当整个机器crash了,ASE(ActiveStandbyElector)在zk的session将会过期,另一个ZKFC将会获取这个事件,引发failover。

  • Active ZKFC crash
    尽管ZKFC设计简单,但是仍然有可能会crash掉,在这个情况下,failover将会被错误的触发。另一个NN的ZKFC将会对ActiveNN调用transitionToStandby让它放弃active lock,然后进行aggressive fencing。尽管会成功,但是会导致进行了一次没有必要的failover

  • Zookeeper crash
    当zk集群crash了,那么所有的ZKFC将收到DISCONNECTED事件。然后ZKFC在本地NN调用enterNeutralMode,除此之外不做任何改变。系统除了不能执行failover之外,与其他情况无异。
    当zk恢复了,clients立马能够重连。而zk能够将之前的session信息重新被各个client进行获取(在启动的一个timeou时间内)。所以所有的nodes将会重新获取session,不需要进行无必要的failover。
    FutureWork:breadcrumb znode在这个情况下可以优先的给予到ActiveNN,在ZK挂掉之前。

您的肯定,是我装逼的最大的动力!