前言:

RDS系统致力于MySQL数据的高可用,高可靠,高性能以及在线扩展功能,实现这些特性的主要逻辑功能都运行在管理服务器上,一旦管理服务器宕机,数据库的在线扩展功能/备份功能/故障恢复功能等都无从谈起。然而,之前RDS系统管理服务器却是单点服务,为了保证整个系统的稳定性,管理服务器需要实现高可用,结合当前主流的高可用方案,决定使用Zookeeper来实现服务的高可用。

基本设计方案原理:

如下图所示,管理服务器A B C会在zk的root节点上注册临时序列节点/root/manager000000001  /root/manager000000002 /root/manager0000000003,序列最小的节点会被选为leader对外提供服务,其他节点作为热备节点随时准备升为leader。在此图中,A是leader,B C是standby。一旦A服务器因为某些原因宕机,zk就会将该服务器注册的临时节点移除掉,然后通知所有其他节点B C,B C会选出序列号最小的节点作为新的leader对外提供服务,此时B就会被选为新主。

血案现场:

会有这么一种比较特殊的场景需要考虑,比如当前leader是A BC都是备机。假如A和zk集群之间的网络出现了异常,A会收到一个连接状态被持久化为Disconnected的event,但是ZK Server并没有在这时移除A注册的临时节点,所以理论上A还是leader直至session timeout,session timeout后zk会将A注册的临时节点移除掉,然后通知B C选出新的leader,显而易见,B因为序列号小会成为新的leader。但是问题来了,session timeout的时候A的客户端并没有接收到任何notification,换句话说,它依然会认为自己是leader,这个时候就出现了这样的场景,A认为自己是leader,而B同样会认为自己是leader,即同时出现两个leader对外提供服务的情况。这很显然是不合理的,但如何深入地理解并解决这个问题呢?

个人认为理解并解决这个问题需要理解下面三个子问题:

1. 理解Zookeeper中Session的含义以及Connection Loss和Session Expired的关系

2. 理解Zookeeper中Session为什么由Server维护,而不由Client维护

3. 理解作为leader的A在整个流程中应该如何转变自己的角色,来避免脑裂

对zookeeper中Connection Loss和Session Expired的理解

Session是指当Client创建一个同Server的连接时产生的会话。连接Connected之后Session状态就开启,Zookeeper服务器和Client采用长连接方式(Client会不停地向Server发送心跳)保证session在不出现网络问题、服务器宕机或Client宕机情况下可以一直存在。因此,在正常情况下,session会一直有效,并且ZK集群上所有机器都会保存这个Session信息。

在ZK中,很多数据和状态都是和会话绑定的,一旦会话失效,那么ZK就开始清除和这个会话有关的信息,包括这个会话创建的临时节点和注册的所有Watcher。

一旦网络连接因为某种原因断开或者zk集群发生宕机,ZK Client会马上捕获到这个异常,封装为一个ConnectionLoss的事件,然后启动自动重连机制在地址列表中选择新的地址进行重连。重连会有三种结果:

(1)在session timeout时间内重连成功,client会重新收到一个syncconnected的event,并将连接重新持久化为connected状态

(2)超过session timeout时间段后重连成功,client会收到一个expired的event,并将连接持久化为closed状态

(3)一直重连不上,client将不会收到任何event

很显然,无论重连成功与否,在session timeout那个重要的时间点,ZK Client是接收不到任何ZK Server清理临时节点的信息的。这也就导致ZK会通知了B C节点A已经不再是Leader,A自身却没有接收到这样的信息,依旧对外提供服务,进而产生脑裂的问题。

Zookeeper中Session为什么由Server维护,而不由Client维护

可能很多朋友看了上面的讨论就会想为什么ZK Client不维护Session信息,如果这样做了,ZK Client就会在Session Timeout时得到相应的通知。

好,现在假如这样实现了,看看会发生什么。设想有这么一种真实场景,某个连接的Session Timeout是15s,ZK集群因为未知原因发生宕机,5min之后集群恢复成功。在Session Timeout时,ZK Client确实可以知道Session失效,然后做降主操作,但是ZK Server却不知道Session已经失效,也就不会通知其他节点选出新的Leader,此时整个系统实际上处于没有Leader的状态。即使5min之后重连成功,因为旧Session对应的临时节点没有被清理且序号最小,ZK依然会认为Leader是该临时节点,而实际上该临时节点对应不到任何的ZK Client,所以这种情况下系统依然选不出Leader。

可见,如果由Client维护Session,在某些场景下(网络异常或者集群宕机时间超过Session Timeout),由于逻辑问题根本选不出Leader。

因此这种方案是不可行的。

那能不能从应用层面避免脑裂问题呢?带着问题进入下个部分。

避免脑裂问题:作为leader的A在整个流程中应该如何转变自己的角色

因为ZK本身的设计使得这种场景下没有一个完美的解决方案,可以考虑采用退化的方案进行处理。

A在接收到DisConnected事件后就降主,不对外提供服务。然后等待接下来的发生的事情,首先可能发生的事件是在Session Timeout时间段内重连成功得到SyncConnected事件,这时A可以重新升级为主,对外提供服务。如果这段时间内没有重连成功,ZK Server在Session Timeout时会将A注册的临时节点移除,并通知B和C A已经停止对外服务了,需要选出新的leader。因为A自己已经降主了,所以在选出新leader后也不会出现多主现象。如果A在Session Timeout时间段外重连又成功了,那此时肯定新的leader已经选出来了,A需要重新注册作为新的备机候选。

可以使用如下的流程图解释这个过程:

这种应用层面的方案在一定程度上解决了脑裂问题,但是会出现一段时间系统无Leader的情况,持续时间最长为Session超时时间。

总结:

结合上述分析,可以针对Session Timeout的问题得出一个应用层面的解决方案,即Client分阶段转变角色方案。如下图所示,箭头上方红色标示表示Client所处不同阶段,箭头下方蓝色标示表示Client在不同阶段的角色转变。

本文章为作者原创

Zookeeper中Session Timeout的那些事的更多相关文章

  1. 关于zookeeper中session timeout

    转自https://yq.aliyun.com/articles/117825?t=t1,主要结论如下: 经过源码分析,得出SessionTimeOut的协商如下: 情况1: 配置文件配置了maxSe ...

  2. 在Django中Session的那点事!

    1.session是什么 首先引入度娘的解释:Session:在计算机中,尤其是在网络应用中,称为“会话控制”.Session 对象存储特定用户会话所需的属性及配置信息.这样,当用户在应用程序的 We ...

  3. 项目server中设置session timeout遇到的问题

    RT:在项目server中的web.xml设置session timeout=10,当10分钟后,继续右键执行jsp文件,运行失败,如下图所示: 但是单独启动tomcat server后,在浏览器中输 ...

  4. ASP.NET中Session的sessionState 4种mode模式

    1. sessionState的4种mode模式 在ASP.NET中Session的sessionState的4中mode模式:Off.InProc.StateServer及SqlServer. 2. ...

  5. java 中Session 持久化问题

    首先: 今天发现了个session 持久化的问题 在Tomcat 停止运行后再启动  session  中保存的东西还会存在 ,百度了一下 原理 1.Session Create 时 2.Sessio ...

  6. zookeeper中Watcher和Notifications

    问题导读:1.zookeeper观察者什么时候调用?2.传统远程轮询服务存在什么问题?3.zk中回调服务的机制是什么?4.zk中watcher为什么不永久注册?5.什么是znode? 在阅读之前首先明 ...

  7. zookeeper中client命令实践

    Welcome to ZooKeeper! 2016-09-14 16:06:04,528 [myid:] - INFO [main-SendThread(master:2181):ClientCnx ...

  8. asp.net中Session过期设置方法

    在Asp.net应用中,很多人会遇到Session过期设置有冲突.其中,可以有四处设置Session的过期时间: 一.全局网站(即服务器)级 IIS-网站-属性-Asp.net-编辑配置-状态管理-会 ...

  9. 【Apache ZooKeeper】理解ZooKeeper中的ZNodes

    理解ZooKeeper中的ZNodes 翻译自:http://zookeeper.apache.org/doc/r3.1.2/zookeeperProgrammers.html ZooKeeper中的 ...

随机推荐

  1. yum install --downloadonly 下载依赖包到本地 但不安装

    如果手动去一个个找依赖是很困难的,即便已经知道名字.版本,下面就依赖系统自带的命令完成该步骤 以java为例,其他安装包只要替换包名 yum install --downloadonly --down ...

  2. Spring AOP项目应用——方法入参校验 & 日志横切

    转载:https://blog.csdn.net/Daybreak1209/article/details/80591566 应用一:方法入参校验 由于系统多个方法入参均对外封装了统一的Dto,其中D ...

  3. Android性能优化-App后台优化

    原文链接 Background Optimizations 前言 后台进程是内存和电池敏感的.一个隐式的broadcast可能会启动很多监听它的后台进程,即使这些进程可能做得工作不多.这可能丢设备性能 ...

  4. weex开发错误汇总

    weex run serve 报UglifyJS错 ANDROID_HOME环境变量 weex build android需要ANDROID_HOME, 请配置 D:\adt-windows-x86_ ...

  5. 《Unix&Linux大学教程》学习笔记5 :正则表达式

    1:Unix下正则表达式规则

  6. VTK计算网格模型上的最短路径

    Dijkstra algorithm to compute the graph geodesic.Takes as input a polygonal mesh and performs a sing ...

  7. ROS actionlib学习(三)

    下面这个例子将展示用actionlib来计算随机变量的均值和标准差.首先在action文件中定义goal.result和feedback的数据类型,其中goal为样本容量,result为均值和标准差, ...

  8. 使用 bibtex4word 实现在 office word 中管理并插入参考文献

    使用 bibtex4word 实现在 office word 中管理并插入参考文献, 简单的步骤流程如下: 1. 下载bibtex4word.zip  (无需安装): 下载地址: http://www ...

  9. [Android实例教程] 教你如何拍照+相册选择图片+剪裁图片完整实现

    [Android实例教程] 教你如何拍照+相册选择图片+剪裁图片完整实现 今天做Android项目的时候要用到图片选择,要实现拍照获取图片和从相册获取图片,并且要求在获取完之后可以裁剪,试了很多方法之 ...

  10. 2.4 Apache Axis2 快速学习手册之XMLBeans 构建Web Service

    4. 使用XMLBeans生成服务(通过xml bean 命令将wsdl 文件生成java 代码) 要使用XMLBeans生成服务,请执行以下步骤. 通过在Axis2_HOME / samples / ...