跳到主要内容

认识

2025年02月22日
柏拉文
越努力,越幸运

一、认识


Redis Sentinel 哨兵机制Redis 为实现高可用性而提供的一套监控和故障转移机制,它主要解决单点故障问题,确保在主节点(master)发生故障时,系统能够自动选举出新的主节点,从而保证服务的连续性。总结来说,Redis Sentinel 通过不断监控、自动故障转移和动态配置管理,为 Redis 部署提供了一种可靠的高可用解决方案。

Redis Sentinel 架构

Preview
graph TD
subgraph Sentinels
S1[Sentinel 1]
S2[Sentinel 2]
S3[Sentinel 3]
end

subgraph Redis Cluster
M[Redis Master]
S1_slave[Redis Slave 1]
S2_slave[Redis Slave 2]
end

%% Sentinel 监控 MasterSlave 节点
S1 -- 监控 --> M
S1 -- 监控 --> S1_slave
S1 -- 监控 --> S2_slave

S2 -- 监控 --> M
S2 -- 监控 --> S1_slave
S2 -- 监控 --> S2_slave

S3 -- 监控 --> M
S3 -- 监控 --> S1_slave
S3 -- 监控 --> S2_slave

%% 数据复制关系
M -- 数据复制 --> S1_slave
M -- 数据复制 --> S2_slave

图中展示了多个 Sentinel 实例如何监控一个 Redis 主节点及其从节点,同时在主节点故障时触发故障转移流程: Sentinel 实例(Sentinel 1、2、3)不断监控 Redis 集群中的主从节点状态; Sentinel 间通过心跳与投票机制协同工作,确保故障能够被及时发现和处理,从而实现高可用性; Redis Master 提供主要的读写服务; Redis Slave 1Redis Slave 2 作为主节点的数据备份,当 Master 出现故障时,其中一个将被 Sentinel 自动升级为新的 Master; 客户端从 Sentinel 来获取 Redis 信息。

Redis Sentinel 哨兵通信机制: Redis Sentinel 实例之间采用一种类似 Gossip 协议的机制进行通信,主要用于: 状态共享, 各个 Sentinel 实例定期交换自己监控到的节点状态,以便集体判断某个节点是否失效; 投票机制, 当出现故障时,Sentinel 会通过投票确定是否对某个节点做出 SDOWN 或者 ODOWN 的判断,同时选举出故障转移的领导者。这种分布式协作机制使得 Sentinel 集群能够在部分 Sentinel 实例失效的情况下依然保持高可用性和一致的决策能力。

Redis Sentinel 哨兵机制原理:

  1. 监控机制: 多个 Sentinel 实例会协同工作,形成一个哨兵集群。这些实例之间通过心跳通信相互验证对方的状态,并共同决定某个节点是否真的失效。Sentinel 实例会不断对集群中的各个 Redis 节点进行健康检查。它们会定时向每个节点发送 PING 请求,期望获得 PONG 响应,以此判断节点是否正常工作。三个定时任务:

    1. 10 秒每个 SentinelMasterSlave 执行 Info, 用于发现 Slave 节点, 并确认主从关系。

    2. 2 秒每个 Sentinel 通过 Master 节点的 Channel 基于 Pub/Sub 交换信息, 通过 __sentinel__:hello 频道交换, 交换对节点的看法和自身信息

    3. 1 秒每个 Sentinel 对其他的 SentinelRedis 执行 Ping

  2. 故障判定: 当 Sentinel 发现某个节点出现异常(例如长时间未响应 PING 请求)时,会触发告警通知。可以通过回调或者其他外部机制将问题报告给管理员或自动化系统。当某个 Sentinel 认为主节点不可达时,它不会立即判定为故障,而是等待其他 Sentinel 的确认。当达到预设的投票比例(即 quorum)时,主节点会被标记为 主观下线(Subjectively Down,SDOWN 和随后 客观下线(Objectively Down,ODOWN主观下线(SDOWN, 每个 Sentinel 会单独判断某个节点是否存在问题, 当一个节点在预设的时间内(通常由参数 down-after-milliseconds 控制)未响应 SentinelPING 请求时,该 Sentinel 会将该节点标记为 主观下线Subjectively Down,SDOWN)。客观下线(ODOWN, 单个 Sentinel 的判断可能受网络波动等因素影响,因此需要多个 Sentinel 实例协同确认, 当达到设定的哨兵投票数(quorum),多个 Sentinel 都认为该节点处于 SDOWN 状态时,节点才会被标记为 客观下线(Objectively Down,ODOWN,这时 Sentinel 集群将认为该节点确实失效,进而触发故障转移流程。在 Sentinel 配置中, sentinel monitor <master-name> <ip> <port> <quorum> quorum(此处为 2), 表示至少需要 2Sentinel 实例同时认为主节点不可用,才能确认其故障,从而启动故障转移流程。

  3. 选举新主节点: 一旦主节点被判定为 ODOWN (通过达到设定的投票门槛,即 客观下线), 首先进行 选举故障转移的领导者, Sentinel 实例之间通过 Gossip 协议相互通信,会在集群中选举出一个 领导者 来协调故障转移过程, 这一选举过程基于各 Sentinel 的配置和投票结果,确保只有一个实例负责整个转移流程。然后 选举一个合适的从节点(slave)作为新的主节点, 从当前主节点的所有从节点中,根据多个因素(例如复制延迟、数据一致性、响应时间等)选出一个最优节点。选举算法确保新主节点能够尽快接替主节点职责,并与原主节点尽可能保持数据同步。确保选出的新主节点能最快、最稳定地承担起主节点的职责。

  4. 更新配置和通知: 故障转移后, 故障转移领导者会通知集群中的其他 SentinelRedis 节点: 重新配置从节点, 将其他从节点的复制源修改为新的主节点, 使它们重新复制数据,实现数据的同步; 更新客户端配置, 将新的主节点信息广播给应用客户端(或通过客户端重连机制自动获取),确保客户端在故障转移后能够连接到正确的节点, Sentinel 作为配置中心,保存当前集群的拓扑结构。当故障转移发生后,客户端可以通过 Sentinel 获取最新的主节点地址,从而重新建立连接。

  5. 配置纪元(Epoch)的更新: 整个转移过程中,Sentinel 会为新的集群状态分配一个新的配置纪元,用以标识当前集群的拓扑变更。这样可以避免由于消息延迟或旧状态混入而导致的不一致问题。

Redis Sentinel 使用场景:

  1. Redis Sentinel 适用于对数据读写高可用性有较高要求的业务场景,比如电商、在线支付等需要持续在线的服务。

Redis Sentinel 注意事项:

  1. 节点数量建议: 为了避免单点故障,通常建议部署至少三个 Sentinel 实例,以便在部分实例失效时,仍能完成故障检测和选举流程。合理设计 Sentinel 的部署方案,建议至少运行 3Sentinel 实例,以防止单点故障对监控和故障转移决策的影响。而且 Sentinel 最好为奇数, 保证选举领导者和新的主节点时的公平。

  2. 网络分区问题: 在网络分区等复杂环境下,可能出现脑裂现象,即多个哨兵集群各自认为自己是主控集群。因此,在部署和配置 Sentinel 时,必须仔细规划网络和投票策略,确保在极端情况下依然能正确选举并稳定运行。

Redis Sentinel 常见配置: Redis Sentinel 的行为可以通过一系列配置参数进行调整,常见的包括:

  • failover-timeout: 定义故障转移整个流程的超时时间,确保故障转移不会长时间悬而未决。

  • parallel-syncs: 定义在故障转移时可以同时重配置的从节点数目,帮助平衡负载与恢复时间。

  • down-after-milliseconds: 定义 Sentinel 多长时间未收到节点响应后,将其标记为 SDOWN

二、安装


Preview

为保证高可用性,建议至少有 3Sentinel 实例分布在不同的物理机器或网络环境中。示例部署(IP 地址和端口仅为示例,可根据实际环境调整):

  • 主节点: 192.168.1.100:6379

  • 从节点1: 192.168.1.101:6379

  • 从节点2: 192.168.1.102:6379

  • Sentinel 实例: 分别部署在上述三台机器上,使用 Sentinel 默认端口 26379

2.1 配置 Redis 主从复制

主节点配置: 在主节点(192.168.1.100)上,使用默认的 redis.conf 配置启动 Redis(无须额外配置)。

主节点启动: 通过 redis-server /path/to/redis.conf 来启动主节点 Redis

从节点配置: 在从节点(例如 192.168.1.101192.168.1.102)上,需要在 redis.conf 中添加如下配置,使其复制主节点的数据。确保主从节点之间网络互通,并且从节点成功与主节点建立复制关系。

slaveof 192.168.1.100 6379

或者

replicaof 192.168.1.100 6379

从节点启动: 通过 redis-server /path/to/redis.conf 来启动从节点 Redis

2.2 Redis Sentinel 配置

在每个 Sentinel 节点上创建一个配置文件,例如命名为 sentinel.conf。以下是一个示例配置:

port ${port}

sentinel monitor mymaster 192.168.1.100 6379 2

sentinel parallel-syncs mymaster 1

sentinel down-after-milliseconds mymaster 5000

sentinel failover-timeout mymaster 10000
  • port: 指定 Sentinel 监听端口

  • quorum(此处为 2): 表示至少需要 2Sentinel 实例同时认为主节点不可用,才能确认其故障,从而启动故障转移流程。

  • mymaster: 是你为主节点设置的名称,在所有 Sentinel 配置中必须保持一致。

  • sentinel monitor: 定义需要监控的主节点, 格式为: sentinel monitor <master-name> <ip> <port> <quorum>

  • sentinel parallel-syncs: 故障转移时,同时进行同步的从节点数量

  • sentinel failover-timeout: 故障转移超时时间(毫秒)

  • sentinel down-after-milliseconds: 指定多长时间(毫秒)内主节点无响应判定为故障

2.3 Redis Sentinel 启动

在每个部署 Sentinel 的服务器上,使用下面的命令启动 Sentinel 进程

redis-sentinel /path/to/sentinel.conf

或者

redis-server /path/to/sentinel.conf --sentinel

这样,三个 Sentinel 实例便会分别启动,并开始监控主从节点的状态。你可以通过如下命令验证 Sentinel 是否正常工作:

redis-cli -p 26379 ping

正常响应应返回 PONG

2.4 Redis Sentinel 验证

使用 Sentinel 提供的命令来查看当前监控的集群信息。例如:

  1. 查看监控的主节点信息:
redis-cli -p 26379 sentinel masters
  1. 查看主节点下所有从节点信息:
redis-cli -p 26379 sentinel slaves mymaster

通过这些命令,你可以确认 Sentinel 已正确发现主从结构及各节点状态。

三、测试


测试故障转移 Failover, 为了验证高可用性,建议进行如下测试步骤:

  1. 模拟主节点故障: 在主节点(192.168.1.100)上执行 SHUTDOWN 命令或直接停止 Redis 服务。

  2. 观察 Sentinel 状态: 过一段时间(取决于 down-after-milliseconds 参数,如 5000 毫秒),使用 Sentinel 命令确认主节点被标记为不可用,并且故障转移流程启动:

redis-cli -p 26379 sentinel masters
  1. 确认新主节点: Sentinel 会从从节点中选举一个作为新的主节点。使用如下命令获取新主节点的地址, 确认返回的新主节点地址是否正确。
redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
  1. 客户端重连: 客户端应通过 Sentinel 获取最新的主节点信息,或者配置支持 Sentinel 的客户端自动进行重连操作,以确保在主节点故障后能够快速切换到新的主节点。