hadoop ha模式下,kill active的namenode节点后,standby的namenode节点没能自动启动

一、背景
     在Hadoop HA模式下,如果直接kill掉active namenode,standby namenode没有自动切换到active状态。

二、问题解决步骤
     1. 查看hadoop安装目录下 etc/hadoop/hadoop-root-zkfc-fang16.hadoop.com.log ,关于zkfc的日志文件。发现如下问题:

       由于在active状态的namenode节点,进行了kill -9 pid号,那么此时8020端口肯定是不开启的状态,那么连接肯定是失败的。

java.net.ConnectException: 
Call From fang.hadoop.com/10.0.2.15 to fang16.hadoop.com:8020 
failed on connection exception: java.net.ConnectException: 
Connection refused


    2.继续查看日志,可以看到trying method 1/1,说明程序使用配置文件配置的fence method和kill掉的active namenode尝试通信。由于已经kill掉,连线肯定失败。

135884 2018-12-03 19:11:47,484 INFO org.apache.hadoop.ha.NodeFencer: ====== Beginning Service Fencing Process... ======
135885 2018-12-03 19:11:47,484 INFO org.apache.hadoop.ha.NodeFencer: Trying method 1/1: org.apache.hadoop.ha.SshFenceByTcpPort(null)
135886 2018-12-03 19:11:47,484 INFO org.apache.hadoop.ha.SshFenceByTcpPort: Connecting to shell04...
135887 2018-12-03 19:11:47,484 INFO org.apache.hadoop.ha.SshFenceByTcpPort.jsch: Connecting to shell04 port 22
135888 2018-12-03 19:11:50,488 WARN org.apache.hadoop.ha.SshFenceByTcpPort: Unable to connect to shell04 as user root
135889 com.jcraft.jsch.JSchException: java.net.NoRouteToHostException: No route to host


  3.既然导致此问题的原因是sshfencing导致的,那么如果尝试使用shell的方式进行fence会怎么样,于是我将dfs.ha.fencing.methods 加上了shell.

<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence
shell(/bin/true)
</value>
</property>


    之所以使用/bin/true 是因为此处无需shell真正的去执行kill namenode 的任务。因为如果active node可连通,已经被sshfence隔离,如果active node 不可连通则由此shell执行(其主要作用是让这一步骤能够进行下去);kill active的namenode节点之后standby namenode 的zkfc log 显示依然会先执行sshfence方式进行隔离,紧随其后再执行shell方式进行隔离,成功解决了这个问题。

三、原理
1.如何在状态切换时避免brain split(脑裂)?
      脑裂:active namenode工作不正常后,zkfc在zookeeper中写入一些数据,表明异常,这时standby namenode中的zkfc读到异常信息,并将standby节点置为active。但是,如果之前的active namenode并没有真的死掉,出现了假死(死了一会儿后又正常了),这样,就有两台namenode同时工作了。这种现象称为脑裂。

     解决方案:standby namenode感知到主用节点出现异常后并不会立即切换状态,zkfc会首先通过ssh远程杀死active节点的 namenode进程(kill -9 进程号)。如果在一段时间内standby的namenode节点没有收到kill执行成功的回执,standby节点会执行一个自定义脚本,尽量保证不会出现脑裂问题!这个机制在hadoop中称为fencing(包括ssh发送kill指令,执行自定义脚本两道保障)。

从解决方案中可知;当发生active节点崩坏时;hadoop会进行以下两个操作:

1)通过ssh kill掉active节点的namenode进程

2)执行自定义脚本

2.问题解惑
      这也就是为什么上面kill掉active的namenode节点之后,standby状态的namenode节点会先尝试连接已经被kill掉的active状态的namenode。如果连接失败,那么就一直重连。知道被kill的节点重新start,此时原先standby状态的节点会变成active,新启动的namenode节点是standby状态。

     如果配置文件配置了shell(/bin/true),那么当sshfencing失败时,直接返回给zookeeper true状态,让其跳过kill这个步骤,直接执行自定义脚本,启动原先standby的节点为active。

原文地址:https://www.cnblogs.com/liuys635/p/12383516.html