集群中的主机经过选举过程由Looking状态变为了Leadering或Following状态。而这些状态之间转移的条件是什么呢?先来个直观的,上状态图。

图 4.1 Cocklebur选举过程中的状态图

  接下来我们对上面的状态图进行逐个分析,并且做出简要的解释说明。如果你对一些概念有所遗忘,请查阅“Cocklebur选举”一章中的名词解释。

Cocklebur状态转义描述

表 4-1 状态转移链接表

状态转移链接

条件

解释

Start->Looking

启动

主机进程实例一旦被启动都设置为Looking状态

Looking->Following

收到对自己加ACK锁主机的Lead消息,或者确定已经存在一个稳定的正常工作的多数派

发现之前给自己加ACK锁的候选者已经成为Leader,说明一定存在一个多数派以其作为Leader,故可以变为Following。另外当一个Looker发现已经存在一个稳定的服务集群(有稳定的Leader和Follower),则它会自动变为Follower加入集群

Looking->Leadering

获得多数派的ACK锁

改进段属于Paxos的第二阶段,候选者赢得了多数派(包括自己)的投票,那么他就多数派申请ACK锁,如果应答允许的节点依然可构成多数派,则说明候选者可以做为Leader

Following->Looking

Leader状态改变为非Leadering或向Leader申请租约超时

当发现Leader已经不是Leader,或者在超时内连接不到Leader,那么说明Leader已经失效,则需要重新选举

Leadering->Looking

租约有效的Follower不足majority-1

Leader维护这租约表,如果有效的Follower不少于majority-1,那么算上Leader自己可构成多数派。如果不满足此条件,则重新选举

*->end

宕机

主机宕机,任何状态归于结束

  状态转移控制流程在源码的Cocklebur.cpp中的process方法中,只用到了一个switch语句。lookForLeader()、Following()、Leadering(),这三个方法完成了三态的运行流程,而每一个方法结束之前,已经确保了全局状态是否改变,这样在某个方法结束后,process方法就可以直接运行当前状态应该运行的控制流程。

  lookForLeader()的算法逻辑我们已经在选举一章中分析过,接下来介绍一下Following()、Leadering()两个方法。这两个方法分别属于Follower对象与Leader对象。

Follower的实现

  Follower每隔一段时间向Leader申请租约。所谓申请租约本质上是一种超时锁,而Follower申请的像是一种读锁,拥有租约之后Follower才能保证能从Leader同步到最新数据。Follower通过心跳的方式向Leader发送一个消息,Cocklebur中消息的结构如下:

struct HBMSG {

1: string my_host_name,

2: i32 cur_node_mode,

3: i64 xid,

}

  这是使用thrift脚本格式去定义的结构体,它包含三个部分:消息发送者的主机名my_host_name、当前状态cur_node_mode、发送者的数据版本xid。

  Follower根据配置定时向Leader发送一个HBMSG,同时也接收一个Leader返回的HBMSG。如果发现返回的HBMSG中Leader状态已经改变,那么它将结束Following流程。Follower的Client实现了一种超时机制,如果连接超时,HBMSG的my_host_name将被置为空串,这说明Leader失效,那么也将结束Following流程。

  而xid的作用就是告知Follower与Leader双方是否需要同步数据。如果Follower发现数据版本xid小于Leader,并且Follower接到Client的同步(sync方法的调用)请求,那么则可以主动的去Leader同步。一般情况下Follower的xid可能会小于Leader一段时间,因为向Follower推送数据是Leader主动完成的。

  当集群刚刚选举完毕,Leader往往还不会对外提供读写服务,因为Cocklebur认为在对外服务之前还有可能加入xid更大的Follower。那么此时Leader便会主动的去pull数据。也就是说Follower只有在client请求其向Leader同步时,Follower才会pull数据。

Leader的实现

  Leader刚刚进入Leadering状态时会为每个多数派其他成员初始化一个租约列表,每个成员的租约期限有个默认值。之后就是不停的去减少租约表中的租约。如果接到了某个Follower申请租约的请求,Leader会为其重新审定租约期限。租约表就好像是一排沙漏,不停的漏沙子,而Follower按照一定时间间隔往自己漏斗中填一把沙子,保证不漏光。如果漏光了,那么Leader则会将其拿掉。如果有新的Follower加入,Leader则为其申请一个新的租约计时器。

  当租约表中的Follower与自己构不成一个多数派时,Leader将会退出Leadering流程。当然这里面可以对一些超时选项加以配置。比如租约表为空之后可以不立即退出,租约被申请多次之后可以提高租约期限等等。

  上文中提到了Leader在决定是否要对外服务之前同步数据的问题。选举完成后,Leader不马上让集群对外服务,而是等待一段时间看看时候还有新的Follower加入。如果这期间加入了Follower,Leader会轮流对其监察(通过HBMSG的方式),若检查发现xid比自己的大,则开始pull数据。数据操作后文会逐渐讲解。

  最后大家可能会有一些疑问,Xid较大,一定代表他数据最新且正确吗?其实在进行同步时Leader会有一些机制去监察数据是否是正确的,整个集群在写数据时每个操作都记录在日志中,在任何时候集群中的每个节点都是一个状态机,只要经历的步骤顺序正确,那么一定可以保证xid的正确性(经历有限相同状态转移之后状态一致)。该部分也将会在后文中阐述。

【分布式协调器】Paxos的工程实现-Cocklebur状态转移的更多相关文章

  1. 【分布式协调器】Paxos的工程实现-cocklebur简介(一)

    初识分布式协调器 分布式协调器的“协调”二字让人摸不到头脑,怎么就协调了,用的着协调吗?实际上这个东西在之前就是为了提供分布式锁服务而设计的,伟大的google公司发明了chubby,雅虎随后也推出了 ...

  2. 中小研发团队架构实践之分布式协调器.Net版ZooKeeper

    原文:中小研发团队架构实践之分布式协调器.Net版ZooKeeper 一.ZooKeeper是什么  Apache ZooKeeper是由Apache Hadoop的子项目发展而来,于2010年11月 ...

  3. 【分布式协调器】Paxos的工程实现-cocklebur简介(二)

    Cocklebur集群的工作原理 在集群正常工作时,整个集群只会有一个Leader,其他都是Follower.Client可以注册到某个Follower,当然也可以注册到Leader,为了减轻Lead ...

  4. 中小研发团队架构实践之分布式协调器ZooKeeper

    一.ZooKeeper是什么  Apache ZooKeeper是由Apache Hadoop的子项目发展而来,于2010年11月正式成为了Apache的顶级项目. ZooKeeper是一个开放源代码 ...

  5. 【分布式协调器】Paxos的工程实现-cocklebur选举

    其实整个项目中一个最主要的看点就是选举算法,而这部分也是逻辑最复杂最难理解的部分.不同的实现在不同的场景下的策略也不尽相同,而且场景非常之多.接下来我们一起来看一下Cocklebur的实现思路. 一个 ...

  6. 中小型研发团队架构实践:分布式协调服务ZooKeeper

    一.ZooKeeper 是什么 Apache ZooKeeper 由 Apache Hadoop 的子项目发展而来,于 2010 年 11 月正式成为了 Apache 的顶级项目. 相关厂商内容 优秀 ...

  7. 【分布式协调】之理解paxos

    感叹一下 不得不说近几年国内软件行业发生了巨大的变化,之前几乎所有应用都围绕桌面展开,而近几年很多让人神魂颠倒的关键词一个接一个的映入眼帘:web2.0.移动应用.云计算.大数据.互联网的浪潮一波接着 ...

  8. SqlServer & Windows 可更新订阅立即更新启用分布式事务协调器(MSDTC)

    原文:SqlServer & Windows 可更新订阅立即更新启用分布式事务协调器(MSDTC) 在可更新订阅中,在订阅设置更新方法,将 "排队更新" 设置为 " ...

  9. 分布式系列文章——Paxos算法原理与推导

    Paxos算法在分布式领域具有非常重要的地位.但是Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更难. 网上有很多讲解Paxos算法的文章,但是质量参差不齐.看了很多关于Paxos的资 ...

随机推荐

  1. Java Security:keytool工具使用说明

    Keytool用法说明 Keytool是一个key与cert的管理工具.使用keytool可以管理public key.private key,以及与key之相关的certificate. 1.com ...

  2. Bootstrap入门(二)栅格

    Bootstrap入门(二)栅格 Bootstrap入门(二)栅格 全局CSS样式--栅格 先引入本地的CSS文件(根据自己的文件夹,有不同的引入地址,我是放在一个新建的名为css的文件夹中) con ...

  3. linux下mysql开启远程访问权限及防火墙开放3306端口

    默认mysql的用户是没有远程访问的权限的,因此当程序跟数据库不在同一台服务器上时,我们需要开启mysql的远程访问权限. 主流的有两种方法,改表法和授权法. 相对而言,改表法比较容易一点,个人也是比 ...

  4. [Java入门笔记] Java语言简介

    前言 学习Java有一段时间了,但是一直缺少一个系统的思想,现在重新通过书籍中.网上的文章,视频等资料,整理与回顾Java的知识点. 言归正传,让我们先从了解Java语言开始. Java语言的由来 J ...

  5. Python时间处理之time模块

    1.time模块简介 time模块提供各种操作时间的函数  说明:一般有两种表示时间的方式:       第一种是时间戳的方式(相对于1970.1.1 00:00:00以秒计算的偏移量),时间戳是惟一 ...

  6. Debian deb源方法升级PHP软件包

    学习Linxu以来,一直坚持编译方式安装软件包,貌似圈子里面也是都倾向于编译,可是搜索到的编译方法都是一堆复制粘贴来的指令, 每个人都这么编译, 却几乎没有人去写明那些五花八门的编译指令代表了什么,是 ...

  7. 初探linux内核编程,参数传递以及模块间函数调用

    一.前言                                  我们一起从3个小例子来体验一下linux内核编程.如下: 1.内核编程之hello world 2.模块参数传递 3.模块间 ...

  8. hadoop如何处理长时间运行不完成的map/reduce 任务?

    如果某一个任务在某个节点上长时间不完成,怎么手动干预来处理这种情况?董西成博客上找到的回答:hadoop中有三种特殊的任务,failed task,killed task和speculative ta ...

  9. org.eclipse.ui.menus扩展点学习

    Eclipse菜单: menu:help?after=addtions menu:navigate?after=open.ext2 menu:window?after=newEditor menu:f ...

  10. [译] OpenStack Liberty 版本中的53个新变化

    一个新的秋季,一个新的OpenStack 版本.OpenStack 的第12个版本,Liberty,在10月15日如期交付,而且目前发行版本已经备好了.那么我们期望能从过去六个月时间的开发中获得些什么 ...