• 【分布式协调器】Paxos的工程实现-Cocklebur状态转移


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

     

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

     

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

    Cocklebur状态转义描述

    表 4-1 状态转移链接表

    状态转移链接

    条件

    解释

    Start->Looking

    启动

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

    Looking->Following

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

    发现之前给自己加ACK锁的候选者已经成为Leader,说明一定存在一个多数派以其作为Leader,故可以变为Following。另外当一个Looker发现已经存在一个稳定的服务集群(有稳定的LeaderFollower),则它会自动变为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。如果发现返回的HBMSGLeader状态已经改变,那么它将结束Following流程。FollowerClient实现了一种超时机制,如果连接超时,HBMSGmy_host_name将被置为空串,这说明Leader失效,那么也将结束Following流程。

      而xid的作用就是告知FollowerLeader双方是否需要同步数据。如果Follower发现数据版本xid小于Leader,并且Follower接到Client的同步(sync方法的调用)请求,那么则可以主动的去Leader同步。一般情况下Followerxid可能会小于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加入。如果这期间加入了FollowerLeader会轮流对其监察(通过HBMSG的方式),若检查发现xid比自己的大,则开始pull数据。数据操作后文会逐渐讲解。

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

     

  • 相关阅读:
    八十四、SAP中的ALV创建之三,创建ALV表格
    八十三、SAP中的ALV创建之二,ALV相关的类型池定义
    八十二、SAP中的ALV创建之一,新建一个程序
    八十一、SAP中的ALV的简介(ABAP List Viewer)
    八十、SAP中数据库操作之 (FOR ALL ENTRIES IN )用法,比较难明白
    七十九、SAP中数据库操作之更新数据,UPDATE的用法
    七十八、SAP中数据库操作之查询条数限制
    七十七、SAP中数据库操作之多表联合查询
    七十六、SAP中数据库的查询用法之 COUNT(总数),SUM(求和),AVG(求平均),GROUP BY(分组)
    七十五、SAP中数据库的使用SQL
  • 原文地址:https://www.cnblogs.com/colorfulkoala/p/3509323.html
Copyright © 2020-2023  润新知