|
| 1 | +## raft成员变更 |
| 2 | + |
| 3 | +成员变更是在集群运行过程中改变一致性协议的节点,增加,减少节点,节点替换。尘缘变更过程中不能影响系统的可用性。 |
| 4 | + |
| 5 | +成员变更也是一个一致性问题,所有节点必须对新成员达成一致,但是成员变更又具有特殊性,在成员变更的过程中,参与投票的成员会发生变化。 |
| 6 | + |
| 7 | +如果把成员变更当做一致性问题,直接向leader 节点发送成员变更请求,leader 同步成员变更日志,达成多数派提交,各个节点成员配置从 旧配置(Cold)切换成新配置 (C new) |
| 8 | + |
| 9 | +因为各个节点变更日志节点的时刻可能不同,造成各个节点从旧成员配置切换到新成员配置的时刻不同,可能在某一时刻Cold 和 C new 同时存在两个互不相交的多数派,进而选举出来两个leader,形成不同的决议,破坏安全性。 |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | +在红箭头处,1 2 形成就旧配置的多数派,3 4 5 形成新配置的多数派,两者不相交可能形成决议冲突。 |
| 14 | + |
| 15 | +## Joint Consensus |
| 16 | + |
| 17 | +> 此办法先让集群从 COLD旧配置切换到一个过渡态的配置COLD,CNEW.此配置称之为联合一致性配置,联合一致性配置是旧成员配置和新新成员配置的组合,一旦联合一致性配置提交,再切换到新配置。 |
| 18 | +
|
| 19 | + |
| 20 | + |
| 21 | + |
| 22 | + |
| 23 | +**希望某一天我能看懂这个图到底画的什么。** |
| 24 | + |
| 25 | +Leader收到成员变更请求后,先想COLD和CNEW发送一条COLD,CNEW日志,此后的所有日志都需要旧多派和新多派的确认,cold,cnew日志在获得了两个多数派同意之后才能提交,此后leader在向cold,cnew同步一条只包含cnew的日志,此后的日志只需要新多派确认,在获得了新多派的确认后即可提交,此时成员变更完成。不在cnew中的成员自动下线。 |
| 26 | + |
| 27 | +成员变更过程中如果发生failover,老leader宕机,老leader宕机,cold,cnew任意一个节点都可能成为新leader,如果新leader没有过渡态的日志,则继续使用cold,截断回滚拥有混合态的follower节点日志,本次成员变更失败。如果新leader上有过渡态的日志,则继续完成没有完成的变更流程。 |
| 28 | + |
| 29 | +### 新成员是先加入后同步数据还是先同步数据后加入 |
| 30 | + |
| 31 | +先加入后同步数据,成员变更可以立即完成,并且只要大多数节点同意即可加入,甚至可以加入不存在的节点,加入后再慢慢同步数据,但是在 数据同步完成之前新成员无法提供服务,但是新成员的加入又让多数派的集合变大,而此时新成员无法提供服务,如果发生了failover,很可能导致无法满足多数成员存活的条件,让服务不可用。新成员先加入再同步数据,简化了成员变更,但是可能降低了服务的可用性。 |
| 32 | + |
| 33 | + |
| 34 | + |
| 35 | +先同步后加入,成员变更需要后台异步进行,先将新成员同步数据,赋予一个特殊的角色learner,只能同步数据不具备投票权,不会增加多数派的集合,等数据同步完成后再加入,正式加入即可开始工作,不影响服务的可用性。成员变更流程变复杂了,因为要先给新成员同步数据后加入,不能加入还不存在的成员。 |
| 36 | + |
| 37 | +### 成员变更日志什么时候生效 |
| 38 | + |
| 39 | +成员变更日志与普通日志不同,并不一定要等到提交 apply后生效。 |
| 40 | + |
| 41 | +对于**leader** : 开始同步成员变更日志之前就可以生效 |
| 42 | + |
| 43 | +对于**follower** :成员变更日志持久化完成后 |
| 44 | + |
| 45 | +因为成员变更日志在没有提交旧生效了,因此如果发生了leader切换可能会回滚。 |
| 46 | + |
| 47 | +### 只有少数成员存活的时候怎么恢复服务 |
| 48 | + |
| 49 | +RAFT只能在大多数节点存活的情况下才能提供服务,实际上有可能遇到只有少部分节点存活的情况,不能达成多数派,不能写入数据,不能做成员变更,那咋办呢。 |
| 50 | + |
| 51 | +因此需要提供一个强制更改成员配置的接口,通过这个接口强制设置每个成员的配置列表,便于从 大多数节点故障中恢复。 |
| 52 | + |
| 53 | +比如只剩下一个节点了,那就强制更改成员配置列表为{s1},这样就形成一个只有S1的成员列表,让这个节点可以继续提供服务,后续再调度其他节点通过成员变更加入。 |
0 commit comments