我为什么会关注到这个问题
在我对yarn进行升级的时候,为了减少对线上作业调度的影响,我先把standby节点进行升级,然后我把原来active节点手动切换成standby,这时候原来的standby应该自动切换成active。但是这一波操作执行yarn rmadmin -getAllServiceState 变成了 两个standby, 当然你如果不管它,一段时间以后也能自动选主
yarn@yarn: yarn rmadmin -getAllServiceState
WARNING: YARN_CONF_DIR has been replaced by HADOOP_CONF_DIR. Using value of YARN_CONF_DIR.
WARNING: YARN_PID_DIR has been replaced by HADOOP_PID_DIR. Using value of YARN_PID_DIR.
hostname1:1234 standby
hostname1:1234 standby
根本原因是什么
结合yarn的版本是 3.3.6 版本
yarn 选主一般是两种方式
- 命令行强制指定主
- zookeeper 指定主(谁先注册znode谁是主)
通过命令行强制指定主的时候并不会主动通知zookeeper更新znode信息,所以你短时间内看到zk内的数据还是原来主的信息,什么时候更新呢,为了不打断刚才的逻辑下面切换拓展再说
解决方案
刚才我们已经知道了,手动通过命令行指定并不能及时更新的原因是主备切换的时候并没有通知zk更新信息,那我们想个办法更新一下不就行了?当然可以了。在下面这个地方加一行代码yarn-code就可以通知zk了。重点关注注释下面那一行代码
synchronized void transitionToStandby(boolean initialize)
throws Exception {
if (rmContext.getHAServiceState() ==
HAServiceProtocol.HAServiceState.STANDBY) {
LOG.info("Already in standby state");
return;
}
LOG.info("Transitioning to standby state");
HAServiceState state = rmContext.getHAServiceState();
rmContext.setHAServiceState(HAServiceProtocol.HAServiceState.STANDBY);
if (state == HAServiceProtocol.HAServiceState.ACTIVE) {
stopActiveServices();
reinitialize(initialize);
/*
* 当由active切换成备的时候不但要stopActiveServices,还要让它重新参与选举,执行rejoinElection 的时候会触发tryDeleteOwnBreadCrumbNode();并reset。
* 有没有同学会有疑问,刚开始启动的时候就是standby,会不会陷入死循环呢?当然不会因为上面已经检测过了,如果是STANDBY,直接return了
*/
rmContext.getLeaderElectorService().rejoinElection();
}
LOG.info("Transitioned to standby state");
}
yarn的主备切换拓展
·下面的主要是我发现的一些问题,并不是标准答案仅作为参考和探讨(不知道是不是和我们配置有关系),因为我也没找到真是的答案
zk 怎么监控yarn active的状态
zk 并不会以一个定时任务去监测yarn的active状态,发现active 故障以后或者变成standby 及时的去切主,而是通过检查session 是不是timeout来判断是不是需要切主。即便调度线程或者其他的线程都退出了,也不会切主,换句话说只要RM不退出,在session timeout之前是不会自动切主的。
具体多久自动执行切主是根据zk的配置的来决定的 zk有个配置如下:也可以不配,默认40秒(40秒怎么来的呢?看下面zk的代码)
maxSessionTimeout=30000
当然这个参数默认是不存在的,这个值的默认值如下maxSessionTimeout 配置
public void setMaxSessionTimeout(int max) {
this.maxSessionTimeout = max == -1 ? tickTime * 20 : max;
LOG.info("maxSessionTimeout set to {} ms", this.maxSessionTimeout);
}
我猜这里可能的原因是:yarn需要做普适,每个厂商对yarn是不是健康的界定标准不一样,这里根据需要可以通过自己定制来实现
yarn ha代码模块里面的HealthMonitor类
可能你和我一样,觉得应该有个地方zk可以以固定的频率去检查yarn active的状态,以便好主动切换,其实并没有,不知道为什么这个HealthMonitor类并没有被加载运行
我的第三个疑问是主备之前为什么不通信呢?
按照正常的想法,备不应该给主通信,检测主的状态,一旦主异常自己不应该赶紧上位吗?
遗憾的是ZKFCRpcServer这个服务也没启动
最后说下我们的问题出在哪
我们session最大超时时间配置成了5分钟,每次都出事故,别问为什么配这么大,我也不知道,我感觉有个10秒钟就行了