Redis(49)Redis哨兵如何实现故障检测和转移?

Redis 哨兵(Sentinel)通过一套精巧的机制实现了故障检测和故障转移。它通过监控 Redis 主节点和从节点的状态,确保在主节点发生故障时,能够及时检测并执行故障转移,确保系统的高可用性。下面详细探讨 Redis 哨兵如何实现故障检测和转移,并结合代码示例加以说明。

故障检测

Redis 哨兵通过以下步骤实现故障检测:

  1. 主观下线(Subjective Down, SDOWN)

    • 每个哨兵定期(默认每秒)向它监视的每个 Redis 实例(主节点和从节点)发送 PING 命令。如果在指定时间内(由 sentinel down-after-milliseconds 配置项决定)没有收到实例的回复,则该哨兵会将该实例标记为主观下线。
    plaintext 复制代码
    sentinel down-after-milliseconds mymaster 5000
  2. 客观下线(Objective Down, ODOWN)

    • 当哨兵将某个实例标记为主观下线后,它会与其他哨兵交换信息。如果足够多的哨兵(由 sentinel monitor mymaster 配置项中的 quorum 决定)都认为该实例不可用,则该实例会被标记为客观下线。
    plaintext 复制代码
    sentinel monitor mymaster 127.0.0.1 6379 2

故障转移

当哨兵系统确定主节点客观下线后,会进行以下步骤实现故障转移:

  1. 选举领头哨兵

    • 所有参与监控的哨兵会进行一次选举,选举出一个哨兵作为领头哨兵,负责执行故障转移操作。选举基于 Raft 算法。
    plaintext 复制代码
    sentinel failover-timeout mymaster 60000
  2. 选择新的主节点

    • 领头哨兵会从现有的从节点中挑选一个作为新的主节点。选择依据包括延迟、同步状态等。
  3. 提升从节点并重新配置

    • 领头哨兵将选定的从节点提升为新的主节点,同时将其他从节点重新配置为新的主节点的从节点。
    plaintext 复制代码
    sentinel parallel-syncs mymaster 1
  4. 通知客户端

    • 哨兵会更新其自己的配置文件,并通知所有 Redis 客户端新的主节点的地址。
    plaintext 复制代码
    sentinel client-reconfig-script mymaster /path/to/notification/script.sh

配置和代码示例

以下是一个完整的 Redis 哨兵配置示例,展示了如何配置和实现故障检测和转移。

主节点配置 (redis-master.conf)

plaintext 复制代码
port 6379
bind 0.0.0.0
dir /var/lib/redis
appendonly yes

启动主节点:

sh 复制代码
redis-server redis-master.conf

从节点配置 (redis-slave.conf)

plaintext 复制代码
port 6380
bind 0.0.0.0
dir /var/lib/redis
appendonly yes
slaveof 127.0.0.1 6379

启动从节点:

sh 复制代码
redis-server redis-slave.conf

哨兵配置 (sentinel.conf)

plaintext 复制代码
port 26379
dir /tmp

# 监控主节点
sentinel monitor mymaster 127.0.0.1 6379 2

# 主节点不可用时间(毫秒)
sentinel down-after-milliseconds mymaster 5000

# 同步从节点的数量
sentinel parallel-syncs mymaster 1

# 故障转移超时时间(毫秒)
sentinel failover-timeout mymaster 60000

# 通知脚本
sentinel client-reconfig-script mymaster /path/to/notification/script.sh

启动哨兵:

sh 复制代码
redis-sentinel sentinel.conf

Java 客户端示例

使用 Jedis 库连接 Redis 哨兵集群,并进行简单的 Redis 操作。

引入 Jedis 库

在 Maven 项目中添加 Jedis 依赖:

xml 复制代码
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.6.3</version>
</dependency>

Java 代码示例

以下 Java 代码展示了如何使用 Jedis 库连接和操作带有 Sentinel 的 Redis 集群。

java 复制代码
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;

import java.util.HashSet;
import java.util.Set;

public class RedisSentinelExample {
    private static final String MASTER_NAME = "mymaster";

    public static void main(String[] args) {
        // 定义 Sentinel 节点
        Set<String> sentinels = new HashSet<>();
        sentinels.add("127.0.0.1:26379");

        // 创建 JedisSentinelPool 对象
        try (JedisSentinelPool sentinelPool = new JedisSentinelPool(MASTER_NAME, sentinels);
             Jedis jedis = sentinelPool.getResource()) {

            // 执行 Redis 操作
            jedis.set("mykey", "myvalue");
            String value = jedis.get("mykey");
            System.out.println("mykey: " + value);

            // 输出连接的主节点信息
            System.out.println("Connected to master: " + jedis.getClient().getHost() + ":" + jedis.getClient().getPort());
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}

总结

Redis 哨兵通过主观下线和客观下线机制实现故障检测,并通过领头哨兵选举、提升从节点为新主节点、重新配置从节点以及通知客户端实现故障转移。合理的哨兵配置可以确保 Redis 集群在主节点故障时能够迅速恢复,提高系统的高可用性。

相关推荐
余衫马3 小时前
Windows 10 环境下 Redis 编译与运行指南
redis·后端
青柠编程5 小时前
基于Spring Boot的竞赛管理系统架构设计
java·spring boot·后端
s9123601016 小时前
【rust】 pub(crate) 的用法
开发语言·后端·rust
夕颜1118 小时前
关于排查问题的总结
后端
码事漫谈8 小时前
揭秘RAG的核心引擎:Document、Embedding与Retriever详解
后端
码事漫谈8 小时前
BM25 检索是什么
后端
Moment9 小时前
写代码也能享受?这款显示器让调试变得轻松又高效!😎😎😎
前端·后端
无双_Joney10 小时前
[更新迭代 - 1] Nestjs 在24年底更新了啥?(bug修复篇)
前端·后端·node.js
stark张宇10 小时前
从入门到放弃?一份让PHP学习持续正反馈的知识清单
后端·php
sunbin10 小时前
软件授权管理系统-整体业务流程图(优化版)
后端