Redis是如何保证高可用的?

93 阅读8分钟

Redis实现高可用主要依赖于其主从复制和Sentinel(哨兵)机制。主从复制可以让一个或多个从服务器复制主服务器的数据,当主服务器发生故障时,可以快速切换到从服务器提供服务。Sentinel机制可以自动监控主服务器的运行状态,当主服务器发生故障时,自动从从服务器中选举一个新的主服务器,然后通知客户端新的主服务器地址,实现故障自动切换。

  • 主从复制:Redis的主从复制功能允许一个Redis服务器(从服务器)复制另一个Redis服务器(主服务器)的数据。复制操作是异步进行的,从服务器会定期更新自己的数据集以保持与主服务器的数据一致。主从复制可以提高Redis的读取性能(通过在从服务器上进行读取操作)和数据安全性(通过在从服务器上备份数据)。
  • 哨兵机制:Redis Sentinel是一个分布式系统,它可以监控多个Redis服务器(包括主服务器和从服务器),并在主服务器发生故障时,自动从从服务器中选举一个新的主服务器。Sentinel通过发送心跳包来监控Redis服务器的运行状态,如果在指定的时间内没有收到主服务器的响应,那么Sentinel就会认为主服务器发生了故障,然后开始故障转移的过程。在故障转移过程中,Sentinel会从所有的从服务器中选举一个新的主服务器,然后通知所有的客户端新的主服务器的地址。

哨兵机制是如何进行主服务器选举的,机制是什么?

Redis Sentinel(哨兵)在主服务器发生故障时,会自动从从服务器中选举一个新的主服务器,这个过程被称为故障转移(failover)。故障转移的过程大致如下:

  1. 检测主服务器故障:Sentinel通过定期向Redis服务器发送心跳包来检测其运行状态,如果在指定的时间内没有收到主服务器的响应,那么Sentinel就会认为主服务器发生了故障。

  2. 开始故障转移:当一个Sentinel检测到主服务器发生故障后,它会向其他的Sentinel发送消息,请求开始故障转移。如果大多数的Sentinel同意开始故障转移,那么就会进入下一步。

  3. 选举新的主服务器:Sentinel会从所有的从服务器中选举一个新的主服务器,选举的规则主要考虑以下几个因素:

    • 数据复制的偏移量:数据复制的偏移量越大,说明从服务器复制的数据越新,优先级越高。
    • 运行时间:运行时间越长,说明从服务器越稳定,优先级越高。
    • Sentinel连接数:Sentinel连接数越多,说明从服务器的网络状况越好,优先级越高。
  4. 执行故障转移:Sentinel会向被选举出的新主服务器发送SLAVEOF NO ONE命令,让其成为新的主服务器。然后,Sentinel会向其他的从服务器发送SLAVEOF命令,让其成为新主服务器的从服务器。

  5. 通知客户端:最后,Sentinel会通知所有的客户端新的主服务器的地址,客户端在收到通知后,会断开与旧主服务器的连接,然后连接到新的主服务器。

以上就是Sentinel进行主服务器选举的大致过程,实际的过程可能会更复杂,涉及到更多的细节和异常处理。

如何选举一个Sentinel节点来执行故障转移?

  1. 选举一个Sentinel节点来执行故障转移的过程是这样的:当一个Sentinel节点检测到主服务器发生故障后,它会向其他的Sentinel节点发送消息,请求开始故障转移。这个请求需要包含两个信息:一个是主服务器的标识,一个是这个Sentinel节点自己的标识。其他的Sentinel节点在收到这个请求后,如果同意开始故障转移,那么就会向这个Sentinel节点发送一个投票。这个过程会持续一段时间(例如10秒),在这段时间内,收到最多投票的Sentinel节点就会被选举出来,然后执行故障转移。
  1. 当一个Sentinel节点收到多个其他Sentinel节点发来的故障转移请求时,它会给第一个收到的请求投票。Redis Sentinel的投票机制是基于"先来先服务"的原则,也就是说,一个Sentinel节点在一次故障转移过程中,只会投票一次,而且是给第一个收到的请求投票。(也可以给自己投票)

  2. 即使一个Sentinel节点已经给其他节点投票了,它仍然可以发起故障转移请求,向其他节点请求投票。只不过,由于它已经投票了,所以它不能再给自己投票,也不能给其他节点投票。 这种设计可以确保在一次故障转移过程中,每个Sentinel节点只投票一次,避免了投票的混乱。同时,由于每个Sentinel节点都可以发起故障转移请求,所以这也提高了故障转移的并行度,可以更快地完成故障转移。

  3. 获取的投票需要超过半数。

  4. 如果在一次投票过程中,没有任何一个Sentinel节点得到的票数超过半数,那么这次故障转移就会失败,主服务器的故障状态不会被改变。然后,Sentinel节点会在一段时间后再次尝试进行故障转移。这个时间间隔是可配置的,默认是2秒。

  5. 在Redis Sentinel系统中,每个Sentinel节点都会维护一个内部的数据结构,用来记录其他Sentinel节点的投票情况。 当一个Sentinel节点发起故障转移请求时,它会向其他的Sentinel节点发送消息,请求它们的投票。其他的Sentinel节点在收到这个请求后,如果同意开始故障转移,那么就会向这个Sentinel节点发送一个投票。这个Sentinel节点在收到投票后,会更新自己的投票记录。 然后,这个Sentinel节点会定期检查自己的投票记录,看看是否有某个Sentinel节点得到的票数超过了半数。如果有,那么就会认为这个Sentinel节点被选举为leader,然后开始执行故障转移。如果没有,那么就会继续等待,直到有一个Sentinel节点得到的票数超过半数,或者超过了故障转移的超时时间。

  1. 脑裂(Split-Brain)是分布式系统中的一个问题,它发生在网络分区的情况下。当网络分区发生后,分布式系统被划分为两个或多个互不通信的部分,每个部分都可能认为自己是唯一活跃的部分,然后开始提供服务。这就可能导致数据的不一致,例如两个部分都接受了写操作,但是这些写操作只在各自的部分内部可见。当网络分区恢复后,这些不一致的写操作就会导致数据的冲突,需要通过一些复杂的机制来解决。

    在Redis Sentinel系统中,为了防止脑裂,通常需要部署奇数个Sentinel节点,并且故障转移需要大多数的Sentinel节点同意。这样,即使网络分区发生,也只有能够联系到大多数Sentinel节点的那一部分可以执行故障转移,其他的部分由于无法得到足够的投票,所以不能执行故障转移。这就避免了在网络分区的情况下出现两个主服务器的问题。

总共有几个Sentinel,有leader和follower吗?

Redis Sentinel(哨兵)系统通常由多个Sentinel节点组成,以提高系统的可用性和容错性。在一个Sentinel系统中,可以有任意多个Sentinel节点,但是通常至少需要三个,以防止在网络分区的情况下出现"脑裂"(即两个节点都认为自己是主节点)。

在Sentinel系统中,并没有明确的leader和follower的角色划分。所有的Sentinel节点都是对等的,它们都会独立地监控和检测Redis服务器的运行状态,然后通过投票的方式来达成一致。

当一个Sentinel节点检测到主服务器发生故障时,它会向其他的Sentinel节点发送消息,请求开始故障转移。如果大多数的Sentinel节点同意开始故障转移,那么就会选举一个Sentinel节点来执行故障转移。这个被选举出来的Sentinel节点在故障转移过程中扮演了"leader"的角色,但是这只是临时的,故障转移完成后,它就会恢复到普通的Sentinel节点。

所以,可以说Sentinel系统是一个无主(masterless)的分布式系统,所有的Sentinel节点都是对等的。