Part 14:Raft论文翻译-《CONSENSUS BRIDGING THEORY AND PRACTICE》(集群成员变更-安全性)
4.1 Safety(安全性)
保证Raft算法的安全性是配置变更的第一个挑战。为了使算法安全,在过渡期间绝不有可能选举两位领导人。如果单个配置变更时更改添加或删除许多服务器,则将集群直接从旧配置切换到新配置可能不安全;无法同时原子切换所有服务器,因此在转换期间集群可能分区(如图4.2所示)。(也就是说,集群配置变更时如果同时变更多个服务器可能导致Raft算法的安全性受到破坏)
image.png大多数成员资格改变算法都引入了额外的机制来处理这些问题。这是我们最初为Raft所做的,但后来我们发现了一个更简单的方法,即不允许成员变更,可能导致不同的多数。因此,Raft限制了允许的更改类型:一次只能从集群中添加或删除一个服务器。成员身份中更复杂的变更可以通过一系列单服务器变更来实现。本章的大部分内容都描述了单服务器方法,这比我们最初的方法更容易理解。为了实现完整性,第4.3节描述了原始方法,它为处理任意配置更改而产生了额外的复杂性。在发现更简单的单服务器更改方法之前,我们在LogCabin中实现了更复杂的方法;但是它使用了在本文写作时更复杂的方法。
image.png当向集群添加单个服务器或从集群中删除单个服务器时,旧集群的任何大多数都与大多数新集群重叠;请参见图4.3。这种重叠阻止了集群分区;就第3.6.3节的安全论证而言,它保证了“选民”的存在。因此,当只添加或删除单个服务器时,直接切换到新的配置是安全的。Raft利用此属性使用很少其他机制安全地更改集群成员身份。
集群的配置信息被保存在Raft的log副本中并且通过单独的log entries来通信。这就综合利用了Raft自己来实现配置信息的备份和持久化保存。这也容许Raft在集群成员变更期间就能够为Client提供服务,这时通过强制为客户端请求和成员变更请求进行排序来实现的。
当Leader接收到一个添加/删除成员的请求时(从Leader的当前配置文件中,Cold),Leader将新的配置(Cnew)作为一个log entry追加至自己的log中并且通过Raft算法备份至其它服务器。新的配置将在每个sever将Cnew添加至自己的log后开始生效:Cnew log entry将备份至Cnew的服务器,Cnew是否提交可通过多数派规则来确定。这就意味着每个sever不需要等到Cnew被提交,每个服务器只需要使用自己的log中最新的配置就好。
配置变更在Cnew完成提交后就完成了。此时,Leader可知道大多数的服务器已经记录了Cnew,Leader也知道任何没有同步到Cnew的server将不会形成多数派(也就是Cnew和Cold不会导致分区的问题),没有Cnew信息的服务器不会被选举为新的Leader。Cnew的提交允许下面3件事情继续发生:
-
Leader能够感知配置变更是否完成;
-
如果配置变更是删除某个服务器,那么这个服务器可以关机(在Cnew提交后);
-
下一步的配置变更就可以开始了,在此之前,相互有重叠的两个配置变更会导致如图4.2所示不安全性的发生。
如上所述,server总是使用最新的配置信息,不管这个配置信息是不是处于已提交状态。因为新一轮的配置变更需要在上一轮配置变更处于已提交后再开始,所以不会出现上述第三条的不安全性。如果集群中的server需要在明确Cnew被提交后才能进行下一次的集群配置变更的话,那就需要Leader收集server对Cnew的保存信息,这将导致Leader花费较长的时间。Leader需要跟踪每个server对Cnew的保存情况,而且sever需要持久化他们的log entry index到磁盘,这些操作在Raft中都是不需要的。取而代之的是,每个server在其log中发现有新的log entry时就可以使用这个log entry,而且Leader知道,只要集群中Cnew被提交后就可以安全的进行下一轮的配置变更。不幸的是,这就隐含了针对配置的log entry可以被删除(当集群中的Leader产生变更时),这种情况下,server需要回滚自己的log到前一个配置状态。
在Raft算法中,是使用RPC调用者的配置信息来进行投票和日志备份的:
- server需要接受来自未包含在其配置信息中的Leader的AppenEntries RPC请求。否则,新服务器将永远不会加入到集群中(它将永不会接受任何log entry当前Leader加入到集群的配置变更信息)。(就是说,如果某个server收到了一个Leader的AppenEntries RPC请求,而这个Leader并没有在这个server的配置信息log中,那么这个server还是要接受并处理这个AppenEntries RPC请求,然后通过日志匹配机制追加新的配置信息log。如果因为这个server种的配置信息没有当前Leader的信息不接受并处理这个AppenEntries RPC请求的话,那极端的情况下,这个server刚加入集群,这个server的配置信息log是空的,如果其不接受Leader的AppenEntries RPC请求的话,那他的配置信息log将还是空的,这个sever无法追加之前的配置信息log)
- server需要接受来自未包含在其配置信息中的Candidate的voteRequest RPC请求(如果这个Candidate有足够新的log和term编号)。这这个server的选票很可能是需要来支撑集群可用性的。例如,在一个由3个server组成的集群中,如果某个server宕机,且这个新加入的server不投票的话,整个集群中只有两个server投票(在一个具有4个server的集群中,多数派的个数是3),这样的话,集群中在宕机的server回复之前将不会出现多数派,那这期间的集群式不可用的。
也就是说,在Raft中,服务器处理RPC请求的时候不用考虑当前的配置信息。
<< 上一章:集群成员变更-总述
下一章:集群成员变更-可用性 >>
网友评论