RAFT 作为协议只能支持领导者选举吗?

Can RAFT as a protocol support only leader election?

我需要定期(比如每分钟)执行某些作业。如果单个节点执行此操作,我们就会出现单点故障。为了避免这种情况,我正在考虑以下方案:

1. Nodes form a raft cluster, with leader election
2. Only the leader executes scheduled jobs
     2.1. Every node checks if it is the leader before executing jobs.
3. Replication of commands is not required, thus we would not have a replicated log

为了实现这一点,只需要领导者选举。那么有没有可能我只实现了RAFT的leader选举部分就实现了呢?这种方法有什么问题吗?

更新 1 以下是错误的假设:(这不可能发生)

*我能看到的一个问题是:在网络分区的情况下,两个领导者的可能性。但我认为我可以忽略这一点。*

更新 2: 不需要重新启动失败的作业

注意:我可能会使用 Zookeeper 或类似的东西来实现这一点,但我的目标是编写我自己的

领导者选举需要一个日志 [领导者做的第一件事是写一个新的日志条目] 和一些其他簿记持久状态,所以即使您不复制任何命令,您也需要一个日志。您不需要非常高性能的日志或传输,但除此之外我认为您将编写 raft 论文中描述的大部分内容。

我建议寻找图书馆或使用现有服务(例如 ZooKeeper 或 etcd)进行协调,话虽如此,如果您的系统可以同时处理 运行 的工作 [就像case in the partition you indicate you can ignore],那么你可以节省很多工作,而且总是运行它在许多主机上。

不,不需要日志。 leader-follower-candidate 状态机和超时足以让主机知道它的领导者。 (在这里试试 https://raft.github.io/ !)

但是,请注意,在很短的时间内,领导者并没有意识到它由于网络分区等原因失去了领导地位。

有两种方法可以解决这个问题。

A。领导者只能在心跳法定人数的最后一次确认后在安全 window 内行动。 这有问题,如更新所示。

回想一下,有一个名为 election_timeout 的参数和另一个未命名的参数,我称之为 hearbeat_timeout.领导者永远不应该在 election_timeout 过去后工作,因为它已经收到了它的最后法定更新减去数据包在网络中传输的一些时间。

|<- hearbeat_timeout ->|
|<---------------- election_timeout ------------------>|
                                   |<- safety_margin ->|
|<----- safe_time_to_do_work ----->|

B。新选出leader时,需要等待一段时间才能担任leader。

|<----------------- election_timeout ----------------->|
|<- hearbeat_timeout ->|
|<---- safety_margin ---->|
                          |<-- safe_time_to_do_work -->|

虽然你会想要记录在给定时间谁是领导者;在应用程序日志或 raft 本身中。

如果你最终使用 raft 日志确保每个领导者提交一些东西,即使它只是一个字符串"host XYZ is leader now" 因为 raft 有时需要 提交以前的值。


更新:所有这些都有一些重要的微妙之处。在某些情况下,过时的主机可以很容易地罢免领导者。

考虑主机没有收到几次心跳的情况。它的选举计时器用完了,它将自己广播为新一代的新候选人。 这随时可能发生,并使上面的 A 的安全裕度无效。 raft 中没有任何东西可以防止这种情况发生,我早就被认为是 raft 的缺点。

如果你想保留方案A,你可以修改协议,让追随者拒绝他们心跳中的选举请求。您还必须确保领导者在某个时候放弃控制权。这将显着减慢故障转移速度。