9.2.4 UpdateServer选主

为了确保一致性,RootServer需要确保每个集群中只有一台UpdateServer提供写服务,这个UpdateServer称为主UpdateServer。

RootServer通过租约(Lease)机制实现UpdateServer选主。主UpdateServer必须持有RootServer的租约才能提供写服务,租约的有效期一般为3~5秒。正常情况下,RootServer会定期给主UpdateServer发送命令,延长租约的有效期。如果主UpdateServer出现异常,RootServer等待主UpdateServer的租约过期后才能选择其他的UpdateServer为主UpdateServer继续提供写服务。

RootServer可能需要频繁升级,升级过程中UpdateServer的租约将很快过期,系统也会因此停服务。为了解决这个问题,RootServer设计了优雅退出的机制,即RootServer退出之前给UpdateServer发送一个有效期超长的租约(比如半小时),承诺这段时间不进行主UpdateServer选举,用于RootServer升级。代码如下:


enum ObUpsStatus

{

UPS_STAT_OFFLINE=0,//UpdateServer已下线

UPS_STAT_NOTSYNC=1,//UpdateServer为备机且与主UpdateServer不同步

UPS_STAT_SYNC=2,//UpdateServer为备机且与主UpdateServer同步

UPS_STAT_MASTER=3,//UpdateServer为主机

};

//RootServer中记录UpdateServer信息的结构

class ObUps

{

ObServer addr_;//UpdateServer地址

int32t inner_port;//UpdateServer内部端口

int64t log_seq_num;//UpdateServer的日志号

int64t lease;//UpdateServer的租约

ObUpsStatus stat_;//UpdateServer状态

};

class ObUpsManager

{

public:

//UpdateServer向RootServer注册

int register_ups(const ObServer&addr,int32_t inner_port,int64_t log_seq_num,int64_t lease,const char*server_version);

//检查所有UpdateServer的租约,RootServer内部有专门的线程会定时调用该函数

int check_lease();

//RootServer给UpdateServer发送租约

int grant_lease();

//RootServer给UpdateServer发送超长租约

int grant_eternal_lease();

private:

ObUps upsarray[MAX_UPS_COUNT];

int32t ups_master_idx;

};


RootServer模块中有一个ObUpsManager类,它包含一个数组upsarray,其中的每个元素表示一个UpdateServer,upsmaster_idx表示主UpdateServer在数组里的下标。ObUps结构记录了UpdateServer的信息,包括UpdateServer的地址(addr)以及内部端口(inner_port),UpdateServer的状态(stat,分为UPS_STAT_OFFLINE/UPS_STAT_NOTSYNC/UPS_STAT_SYNC/UPS_STAT_MASTER这四种),UpdateServer的日志号(log_seq_num)以及租约(lease_)。

UpdateServer首先通过register_ups向RootServer注册,将它的信息告知RootServer。一段时间之后,RootServer会从所有注册的UpdateServer中选取一台日志号最大的作为主UpdateServer。ObUpsManager类中还有一个check_lease函数,由RootServer内部线程定时调用,如果发现UpdateServer的租约快要过期,则会通过grant_lease给UpdateServer延长租约。如果发现主UpdateServer的租约已经失效,则会从所有Update-Server中选择一个日志号最大的UpdateServer作为新的主UpdateServer。另外,Root-Server还可以通过grant_eternal_lease给UpdateServer发送超长租约。