心跳Server端设计:
server端的心跳设计要稍微复杂一些,为了保证server端主从切换过程中,client不发生断连。client端与server在建立心跳时,server端需要将心跳信息进行持久化。因此server的心跳需要依赖一个可靠的存储系统,一般选择zookeeper,etcd这种分布式协调组件。
与server的心跳建立:
a. worker2启动后只有master的列表,并不知道哪个是leader,因此先广播bootstrap信息。
b. 只有leader节点响应bootstrap信息,leader生成session id并持久化,只有持久化成功后才可以返回bootstrap ack 给worker2,并标记worker2为Up。
c. leader将分配的session id 自己的epoch等信息返回给worker2。worker2收到ack信息本地记录leader的epoch,sessionid等信息作为后续发送心跳的凭证,并进入connected状态。
d. bootstrap ack消息还需要携带,心跳超时时间,假心跳超时时间。
server端故障切主:
a. leader故障后,新的leader接管了业务,并且从持久化存储中load起worker2的相关信息,主要是sessionid信息。
b. 新leader加载worker2的心跳信息后,会重新计时,只要worker2在超时时间内重新发送心跳就不会产生断连事件。
c. 为了server切主过程中,不对原有心跳有影响,server端故障切换时延一般设置为,server端与client端心跳的0.6.
d. worker2收到新的HB ack后更新新的leader地址与epoch信息,整个流程对外是透明的。
leader与worker同时故障:
因为存在leader与worker同时故障场景,例如:worker与leader在同一台服务器,而服务器掉电或者服务器重启。这种场景下我们也要求故障检测也可以发现worker发生过故障。
a. leader与worker2 同时故障,leader切主并加载worker2的心跳信息。
b. 这时新leader不会认为worker2发生了故障,而是会重新计时,等待worker2的HB消息。
c. 由于worker2故障了,因此新leader等不到worker2的HB消息,最终会导致leader发现worker2超时。
d. 即使在超时时间内,worker2重启,worker2重启后会先发送bootstrap消息,新leader收到worker2的bootstrap消息后会先忽略,因为此时worker2还在Up状态,不会接收bootstrap消息只会接收HB消息。
e. 等leader发现worker2超时后,将worker2的状态设置为down,这时worker2的bootstrap消息才会被处理。
从上面的流程可以看出,无论leader和worker如何故障,都不会影响故障事件的检测,最终都会检测出来,只是有可能延迟。