领导选举
比如现在有个 A、B、C 三个节点。
- 每个节点有个自旋时间(150ms-300ms),自旋时间到了,就成为候选人,并且通知其他的节点他已经是候选人了。
- 比如 A 节点成了候选人,通知 B 、C,那么B C 就重置自旋时间。
- 候选人 A 会给自己投票,然后 B、C 会给最先收到的投票请求的节点投票。每个节点只能投票一次。投票
- 比如 B、C 给 A 投票。A 成为了 Leader
- Leader A 给 B、C 发送更新日志。
- Leader A 和随从 B、C 之间会维持心跳检测,定期发送信息来确定节点是否存活(随从收到心跳检测消息后,会重置自旋时间)
一般要求集群节点个数为奇数个,这样投票就不容易出现两个候选人票数相同的情况。(票数相同,重新自选投票)
日志复制
比如现在有个 A、B、C 三个节点,A 是 Leader,B、C 是候选者。
- Leader A 收到更新数据为 5 的请求,则生成 log。
- 下一次心跳检测时,A 把 log 也发送给 B、C
- B、C 收到 log 后,回复给 Leader A
- A 收到回复后,提交更新,把数据更新成 5
- 下一次心跳检测时,A 发送指令,让 B、C 节点也提交数据。
- B、C 提交数据,然后回复给 A。
出现网络分区
-
假如出现网络分区,区之间不通信。那么分区各自进行领导选取和日志复制。
-
如果网络分区恢复,那么会选择选举轮数多的节点为新 leader。比如图中,leader E 进行了四轮选举,而 leader B 只进行了一轮,所以选择 E 为新 leader,而 B 和 A 中未提交的数据要进行回滚,并且同步新 leader 的数据。
能满足可用性吗?
不能,在选举领导期间,对所有请求会返回不可用。