在 Raft 论文中,他们提到所有客户端交互都发生在领导节点上。我不明白的是,领导者一直在变化。因此,假设我的集群位于负载均衡器后面。如何通知负载均衡器领导者已更改?或者如果我是正确的,负载均衡器是否可以向任何节点(跟随者或领导者)发送客户端请求,并且跟随者节点有责任将请求发送给领导者?
2 回答
投票结束后,您将拥有一个领导者(新的或旧的)。领导者有责任通知网络中的所有节点定期(小于网络的保活时间但大于最大往返时间)向所有节点发送心跳。
您的负载均衡器应在每次收到心跳时更新领导者。负载均衡器将只向领导者发送数据,因为根据 raft 算法,所有客户端请求都直接发送给领导者,其他节点不能发送数据,只能发送确认投票和附加命令。
这里有一个非常好的演示文稿:- Raft: Log-Replication
实际上有两种方法可以做到这一点:负载均衡器需要了解领导者的位置,或者追随者可以将请求代理到领导者。
通过追随者将客户端请求代理给领导者并没有错,事实上它可以带来很大的好处。许多 Raft 实现允许客户端读取跟随者,同时保持顺序一致性。这仍然可以通过负载均衡器向任意节点发送请求来安全地完成,如果客户端跟踪它看到的最后一个索引并在每个请求中发送该索引以确保它没有看到状态及时返回。我不会在这里写完整的算法,但这在你应该参考的 Raft 论文中有描述。
但是在某些情况下,以这种方式使用负载均衡器可能会变得不安全。如果允许客户端发送多个并发请求,负载均衡器可以通过不同的节点路由这些请求,并且它们可能会乱序到达领导者。这可以通过将序列号附加到客户端请求并重新排序领导者上的请求来解决。但要做到这一点,实现必须包括会话以允许领导者跟踪每个客户端的状态。
不过,通常情况下,Raft 客户端会连接到特定节点并尽可能长时间地与它们保持连接,以减少在切换服务器时维护一致性的开销。如果实现支持从跟随者读取,则切换服务器的成本仍然很高,因为服务器必须等待状态赶上以保持顺序一致性。