3

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

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 或类似的东西来实现这一点,但我的目标是编写自己的

4

2 回答 2

1

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

我建议寻找一个库或使用诸如 ZooKeeper 或 etcd 之类的现有服务进行协调,话虽如此,如果您的系统可以处理同时运行的作业 [就像您表示可以忽略的分区中的情况一样],那么您可以为自己节省大量工作,并且始终在多个主机上运行它。

于 2018-01-17T05:27:49.777 回答
1

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

但是,请注意,领导者在短时间内没有意识到由于网络分区等原因而失去了领导权。

有两种方法可以处理这个问题。

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

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

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

。When a leader is newly elected, it should wait some time before acting as a leader.

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

但是,您需要记录在给定时间谁是领导者;在应用程序日志或 raft 本身中。

如果您最终使用了 raft 日志,请确保每个领导者都提交了一些内容,即使它只是一个字符串“主机 XYZ 现在是领导者”,因为 raft 有时需要日志向前移动以提交以前的值。


更新:这一切都有一些重要的微妙之处。有一种情况,一个过时的主机可以很容易地废黜一个领导者。

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

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

于 2018-01-23T06:27:58.920 回答