我们有一个Redis主从交换机维护计划,该计划手动将一个从服务器提升为主服务器,同时保持可写状态。它的工作原理是:
一开始我们就有
Master(M) <-- Slave(S1)
,我们要使S1成为新的主服务器。因此,我们添加了一个新的slave(S2):
M <-- S1 <-- S2
并使指向M的域名指向S1。 DNS需要时间才能生效,因此在这段时间内,来自客户端的写入可能同时到达M和S1:
M <-- S1 <-- S2
^ ^ ^
|(Write) |(Write) |(Read)
Client1 Client2 Client3
没关系,读取可以看到停滞的数据,我们可以接受最终的一致性。由于对M和S1的写操作最终都将复制到S2,因此不会丢失任何数据。
过一会儿(DNS生效),M将不再对其进行写操作,因此我们可以放心地将其删除,以使S1成为新的主控器:
M(previously S1) <-- S2
在我们尝试将Redis升级到4.x版本之前,上面的主从交换机维护计划是行之有效的。
在Redis Replication doc中,它表示:
还要注意,由于Redis 4.0从属写入仅是本地的,因此不会传播到连接到实例的子从属。子从属将始终接收与顶级主服务器发送给中间从属的复制流相同的复制流。因此,例如在以下设置中:
A ---> B ---> C
即使B是可写的,C也不会看到B的写操作,而是具有与主实例A相同的数据集。
在这种情况下,如果我们升级到Redis 4.x,则以下内容
M <-- S1 <-- S2
^ ^ ^
|(Write) |(Write) |(Read)
Client1 Client2 Client3
S1将不再将其写操作传播到S2,因此S2中的读操作将丢失数据!
所以我的问题是,如何使我们的常规主从交换机维护计划在Redis版本4下再次工作?