Skip to content

Redis 主从架构迁移到 Sentinel 架构

迁移前准备

环境检查

  1. Redis 版本检查

    • 确保 Redis 版本 >= 2.8.0(Sentinel 要求)
    • 推荐使用 Redis 5.0+,功能更完善,稳定性更好
  2. 主从架构状态检查

    bash
    # 检查主节点信息
    redis-cli -h master -p 6379 info replication
    
    # 检查从节点同步状态
    redis-cli -h slave1 -p 6379 info replication | grep -E "role|master_host|master_link_status|slave_repl_offset"
    redis-cli -h slave2 -p 6379 info replication | grep -E "role|master_host|master_link_status|slave_repl_offset"
  3. 系统资源检查

    • 确保有足够的 CPU、内存和磁盘空间部署 Sentinel 节点
    • 检查网络连接,确保 Sentinel 节点之间以及与 Redis 节点之间网络通畅

数据备份

  1. 主节点数据备份

    bash
    # 生成 RDB 快照
    redis-cli -h master -p 6379 bgsave
    
    # 等待快照生成完成
    redis-cli -h master -p 6379 LASTSAVE
    
    # 复制备份文件到安全位置
    cp /var/lib/redis/dump.rdb /backup/redis/$(date +%Y%m%d)-master-dump.rdb
  2. 从节点数据备份(可选)

    • 对于重要数据,建议同时备份从节点数据
    • 可以通过复制从节点的 RDB 文件实现

准备配置文件

  1. Redis 配置文件优化

    txt
    # 确保主从节点都启用了持久化
    appendonly yes
    appendfsync everysec
    
    # 启用保护模式
    protected-mode yes
    
    # 配置密码(如果需要)
    requirepass your_redis_password
    masterauth your_redis_password
  2. Sentinel 配置文件准备

    txt
    # 端口
    port 26379
    
    # 守护进程模式
    daemonize yes
    
    # 日志文件
    logfile "/var/log/redis/sentinel.log"
    
    # 工作目录
    dir "/tmp"
    
    # 监控的主节点
    # sentinel monitor <master-name> <ip> <redis-port> <quorum>
    sentinel monitor mymaster 127.0.0.1 6379 2
    
    # 主节点密码
    sentinel auth-pass mymaster your_redis_password
    
    # 主节点超时时间
    sentinel down-after-milliseconds mymaster 30000
    
    # 故障转移超时时间
    sentinel failover-timeout mymaster 180000
    
    # 故障转移时并行同步的从节点数量
    sentinel parallel-syncs mymaster 1

部署规划

  1. Sentinel 节点数量

    • 建议部署 3 个或 5 个 Sentinel 节点
    • 奇数个节点可以避免脑裂问题
    • 节点之间最好分布在不同的物理机器上
  2. 部署位置

    • 可以与 Redis 节点部署在同一台机器上
    • 推荐部署在不同的机器上,提高可靠性
    • 确保 Sentinel 节点之间网络通畅
  3. 端口规划

    • 默认端口:26379
    • 可以根据需要修改,但所有 Sentinel 节点的端口应保持一致

Sentinel 部署

安装 Sentinel

  1. 使用包管理器安装

    bash
    # CentOS/RHEL
    yum install redis-sentinel
    
    # Ubuntu/Debian
    apt-get install redis-sentinel
  2. 从源码安装

    bash
    # 下载并解压 Redis 源码
    wget https://download.redis.io/releases/redis-6.2.6.tar.gz
    tar xzf redis-6.2.6.tar.gz
    cd redis-6.2.6
    
    # 编译安装
    make
    make install
    
    # 复制 Sentinel 配置文件
    cp sentinel.conf /etc/redis/

配置 Sentinel

  1. 修改 Sentinel 配置文件

    bash
    # 编辑 Sentinel 配置文件
    vi /etc/redis/sentinel.conf
    
    # 修改以下配置
    port 26379
    daemonize yes
    logfile "/var/log/redis/sentinel.log"
    dir "/tmp"
    sentinel monitor mymaster <master-ip> <master-port> 2
    sentinel auth-pass mymaster <redis-password>
    sentinel down-after-milliseconds mymaster 30000
    sentinel failover-timeout mymaster 180000
    sentinel parallel-syncs mymaster 1
  2. 配置文件说明

    • sentinel monitor:定义要监控的主节点
      • mymaster:主节点名称,可自定义
      • <master-ip>:主节点 IP 地址
      • <master-port>:主节点端口
      • 2:quorum 值,表示需要多少个 Sentinel 节点同意才能判定主节点故障
    • sentinel auth-pass:主节点密码(如果有)
    • sentinel down-after-milliseconds:判定主节点故障的超时时间(毫秒)
    • sentinel failover-timeout:故障转移超时时间(毫秒)
    • sentinel parallel-syncs:故障转移时并行同步的从节点数量

启动 Sentinel

  1. 启动单个 Sentinel 节点

    bash
    redis-sentinel /etc/redis/sentinel.conf
  2. 使用 systemd 启动(推荐)

    bash
    # 创建 systemd 服务文件
    vi /etc/systemd/system/redis-sentinel.service
    
    # 内容如下
    [Unit]
    Description=Redis Sentinel
    After=network.target
    
    [Service]
    Type=forking
    ExecStart=/usr/local/bin/redis-sentinel /etc/redis/sentinel.conf
    ExecStop=/usr/local/bin/redis-cli -p 26379 shutdown
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    
    # 重新加载 systemd 配置
    systemctl daemon-reload
    
    # 启动并启用 Sentinel 服务
    systemctl start redis-sentinel
    systemctl enable redis-sentinel
    
    # 检查 Sentinel 状态
    systemctl status redis-sentinel
  3. 验证 Sentinel 启动

    bash
    # 检查 Sentinel 进程
    ps -ef | grep redis-sentinel
    
    # 检查 Sentinel 日志
    tail -f /var/log/redis/sentinel.log
    
    # 使用 redis-cli 连接 Sentinel
    redis-cli -p 26379 info sentinel

部署多个 Sentinel 节点

  • 重复上述步骤,部署 3 个或 5 个 Sentinel 节点
  • 确保所有 Sentinel 节点的配置文件中,sentinel monitor 指向同一个主节点
  • 确保所有 Sentinel 节点之间网络通畅

迁移过程

验证主从架构状态

在开始迁移前,确保主从架构状态正常:

bash
# 检查主节点信息
redis-cli -h master -p 6379 info replication

# 检查从节点信息
redis-cli -h slave1 -p 6379 info replication
redis-cli -h slave2 -p 6379 info replication

启动 Sentinel 集群

  1. 启动所有 Sentinel 节点

    • 按照前面的步骤启动 3 个或 5 个 Sentinel 节点
    • 确保所有节点都能正常连接到主节点
  2. 验证 Sentinel 集群状态

    bash
    # 检查 Sentinel 信息
    redis-cli -p 26379 info sentinel
    
    # 查看 Sentinel 监控的主节点
    redis-cli -p 26379 sentinel masters
    
    # 查看 Sentinel 监控的从节点
    redis-cli -p 26379 sentinel replicas mymaster
    
    # 查看所有 Sentinel 节点
    redis-cli -p 26379 sentinel sentinels mymaster

客户端迁移

  1. 修改客户端配置

    • 将客户端连接地址从固定的主节点地址改为 Sentinel 集群地址
    • 客户端需要支持 Sentinel 协议
  2. 客户端配置示例(以 Java Jedis 为例)

    java
    Set<String> sentinels = new HashSet<>();
    sentinels.add("sentinel1:26379");
    sentinels.add("sentinel2:26379");
    sentinels.add("sentinel3:26379");
    
    JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels, "your_redis_password");
    Jedis jedis = pool.getResource();
  3. 逐步迁移客户端

    • 建议分批次迁移客户端,避免一次性切换导致的系统压力
    • 监控系统性能,确保迁移过程中系统稳定

监控迁移过程

  1. 监控 Sentinel 日志

    bash
    tail -f /var/log/redis/sentinel.log
  2. 监控 Redis 节点状态

    bash
    # 定期检查主从节点状态
    redis-cli -h master -p 6379 info replication
    
    # 检查 Sentinel 状态
    redis-cli -p 26379 info sentinel
  3. 监控系统性能

    • 监控 CPU、内存、网络等系统资源使用率
    • 监控 Redis 命令执行延迟
    • 监控客户端连接数

验证和测试

验证 Sentinel 架构状态

  1. 检查 Sentinel 集群状态

    bash
    # 检查所有 Sentinel 节点是否正常运行
    for port in 26379 26380 26381; do
        redis-cli -p $port info sentinel
    done
    
    # 检查主从节点状态
    redis-cli -h master -p 6379 info replication
  2. 验证 Sentinel 发现机制

    bash
    # 查看 Sentinel 发现的主从节点
    redis-cli -p 26379 sentinel masters
    redis-cli -p 26379 sentinel replicas mymaster
  3. 验证配置中心功能

    bash
    # 修改 Sentinel 配置
    redis-cli -p 26379 sentinel set mymaster down-after-milliseconds 50000
    
    # 检查配置是否同步到其他 Sentinel 节点
    redis-cli -p 26380 sentinel master mymaster | grep down-after-milliseconds

故障转移测试

  1. 手动触发故障转移

    bash
    # 使用 Sentinel 命令手动触发故障转移
    redis-cli -p 26379 sentinel failover mymaster
  2. 监控故障转移过程

    bash
    # 实时查看 Sentinel 日志
    tail -f /var/log/redis/sentinel.log
    
    # 监控主节点变化
    watch -n 1 redis-cli -h master -p 6379 info replication
  3. 验证故障转移结果

    bash
    # 检查新的主节点
    redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
    
    # 检查从节点状态
    redis-cli -h new-master -p 6379 info replication
  4. 模拟主节点故障

    bash
    # 停止主节点 Redis 服务
    systemctl stop redis-master
    
    # 监控 Sentinel 自动故障转移
    tail -f /var/log/redis/sentinel.log
    
    # 验证故障转移完成后,重新启动原主节点
    systemctl start redis-master

数据一致性验证

  1. 检查数据完整性

    bash
    # 比较故障转移前后的键数量
    OLD_KEY_COUNT=$(redis-cli -h old-master -p 6379 DBSIZE)
    NEW_KEY_COUNT=$(redis-cli -h new-master -p 6379 DBSIZE)
    
    if [ "$OLD_KEY_COUNT" -eq "$NEW_KEY_COUNT" ]; then
        echo "数据完整性验证通过"
    else
        echo "数据完整性验证失败"
    fi
  2. 检查关键数据

    • 随机检查一些关键数据,确保数据正确
    • 可以使用 RANDOMKEY 命令随机获取键,然后检查其值
  3. 验证从节点同步

    bash
    # 检查所有从节点的复制偏移量
    for slave in slave1 slave2; do
        redis-cli -h $slave -p 6379 info replication | grep slave_repl_offset
    done

故障转移测试

测试场景设计

  1. 主节点故障测试

    • 模拟主节点崩溃
    • 验证 Sentinel 自动故障转移
    • 验证从节点提升为主节点
  2. 从节点故障测试

    • 模拟从节点崩溃
    • 验证 Sentinel 检测到从节点故障
    • 验证系统仍然正常运行
  3. 网络分区测试

    • 模拟网络分区,将主节点与 Sentinel 节点隔离
    • 验证 Sentinel 检测到网络分区
    • 验证故障转移过程

测试步骤

  1. 主节点故障测试

    bash
    # 停止主节点 Redis 服务
    systemctl stop redis-master
    
    # 监控故障转移过程
    tail -f /var/log/redis/sentinel.log
    
    # 验证新主节点选举
    redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
    
    # 重启原主节点
    systemctl start redis-master
    
    # 验证原主节点成为从节点
    redis-cli -h master -p 6379 info replication | grep role
  2. 从节点故障测试

    bash
    # 停止一个从节点
    systemctl stop redis-slave1
    
    # 监控 Sentinel 日志
    tail -f /var/log/redis/sentinel.log
    
    # 检查 Sentinel 状态
    redis-cli -p 26379 sentinel replicas mymaster
    
    # 重启从节点
    systemctl start redis-slave1
    
    # 验证从节点重新加入集群
    redis-cli -p 26379 sentinel replicas mymaster
  3. 网络分区测试

    bash
    # 使用 iptables 模拟网络分区
    iptables -A INPUT -s sentinel1-ip -j DROP
    iptables -A OUTPUT -d sentinel1-ip -j DROP
    
    # 监控 Sentinel 日志
    tail -f /var/log/redis/sentinel.log
    
    # 恢复网络连接
    iptables -D INPUT -s sentinel1-ip -j DROP
    iptables -D OUTPUT -d sentinel1-ip -j DROP
    
    # 验证集群恢复正常
    redis-cli -p 26379 info sentinel

测试结果验证

  1. 故障转移时间

    • 记录故障转移开始到完成的时间
    • 验证故障转移时间是否在预期范围内(通常为几秒到几十秒)
  2. 数据一致性

    • 验证故障转移前后数据是否一致
    • 检查是否有数据丢失
  3. 系统可用性

    • 验证故障转移过程中,系统是否仍然可用
    • 检查客户端是否能够自动连接到新的主节点
  4. Sentinel 稳定性

    • 验证 Sentinel 节点在故障转移过程中是否稳定运行
    • 检查 Sentinel 日志中是否有错误信息

常见问题和解决方案

Sentinel 无法发现主节点

问题描述:Sentinel 无法发现或连接到主节点

可能原因

  • 主节点防火墙阻止了 Sentinel 连接
  • 主节点配置了 bind 选项,只允许特定 IP 访问
  • 主节点保护模式(protected-mode)未正确配置
  • 主节点密码错误

解决方案

  • 检查主节点防火墙设置,确保允许 Sentinel 端口访问
  • 调整主节点的 bind 选项,允许 Sentinel 节点访问
  • 确保主节点的保护模式配置正确,或禁用保护模式
  • 检查 Sentinel 配置中的主节点密码是否正确

故障转移失败

问题描述:主节点故障时,Sentinel 无法成功进行故障转移

可能原因

  • Sentinel 节点数量不足,无法达成 quorum
  • 所有从节点都不可用或数据过旧
  • Sentinel 配置中的 failover-timeout 过短
  • 从节点配置了 slave-priority 为 0,无法被选举为主节点

解决方案

  • 确保部署了足够数量的 Sentinel 节点(3 个或 5 个)
  • 确保至少有一个从节点数据同步正常
  • 调整 failover-timeout 配置,延长故障转移超时时间
  • 检查从节点的 slave-priority 配置,确保有可用的从节点可以被选举

客户端无法自动连接到新主节点

问题描述:主节点故障转移后,客户端无法自动连接到新的主节点

可能原因

  • 客户端不支持 Sentinel 协议
  • 客户端配置中的 Sentinel 地址不正确
  • 客户端连接超时时间过短
  • 客户端未正确处理 Sentinel 连接异常

解决方案

  • 使用支持 Sentinel 协议的客户端库
  • 检查客户端配置中的 Sentinel 地址是否正确
  • 调整客户端连接超时时间
  • 确保客户端正确处理 Sentinel 连接异常,实现自动重连

Sentinel 节点频繁重启

问题描述:Sentinel 节点频繁重启

可能原因

  • Sentinel 配置文件错误
  • 系统资源不足
  • Sentinel 日志文件权限问题
  • 网络不稳定,频繁断开连接

解决方案

  • 检查 Sentinel 配置文件,确保配置正确
  • 增加系统资源,确保有足够的 CPU 和内存
  • 检查 Sentinel 日志文件权限,确保 Sentinel 可以写入日志
  • 检查网络连接,确保网络稳定

脑裂问题

问题描述:网络分区导致出现多个主节点

可能原因

  • 网络分区将集群分成多个部分,每个部分都有足够的 Sentinel 节点
  • Sentinel 配置中的 quorum 值设置过低

解决方案

  • 部署奇数个 Sentinel 节点,避免网络分区时出现平局
  • 调整 quorum 值,提高故障转移的门槛
  • 使用 min-slaves-to-writemin-slaves-max-lag 配置,限制主节点在从节点不足时的写入

最佳实践

部署最佳实践

  1. Sentinel 节点数量

    • 建议部署 3 个或 5 个 Sentinel 节点
    • 奇数个节点可以避免脑裂问题
  2. 部署位置

    • 将 Sentinel 节点分布在不同的物理机器上
    • 最好分布在不同的可用区或数据中心
    • 确保 Sentinel 节点之间网络通畅
  3. 配置最佳实践

    • 设置合理的 down-after-milliseconds 值(建议 30000 毫秒)
    • 设置足够长的 failover-timeout 值(建议 180000 毫秒)
    • 设置合适的 parallel-syncs 值(建议 1 或 2)
    • 启用 protected-mode,提高安全性
    • 配置正确的密码,保护 Redis 和 Sentinel

运维最佳实践

  1. 监控

    • 监控 Sentinel 节点状态
    • 监控主从节点状态
    • 监控故障转移事件
    • 监控系统资源使用率
  2. 日志管理

    • 定期清理 Sentinel 日志
    • 配置适当的日志级别
    • 集中管理日志,便于分析
  3. 备份

    • 定期备份 Redis 数据
    • 备份 Sentinel 配置文件
    • 备份主从节点配置文件
  4. 升级

    • 定期升级 Redis 和 Sentinel 版本
    • 升级前进行充分测试
    • 采用滚动升级方式,避免系统中断
  5. 故障演练

    • 定期进行故障转移演练
    • 测试不同故障场景
    • 验证系统的可靠性和可用性

客户端最佳实践

  1. 客户端选择

    • 使用支持 Sentinel 协议的客户端库
    • 选择成熟、稳定的客户端库
  2. 连接池配置

    • 配置合理的连接池大小
    • 设置适当的连接超时时间
    • 启用连接池的健康检查
  3. 异常处理

    • 正确处理连接异常
    • 实现自动重连机制
    • 处理故障转移期间的请求失败
  4. 负载均衡

    • 考虑在多个 Sentinel 节点之间进行负载均衡
    • 避免所有客户端都连接到同一个 Sentinel 节点

迁移后的优化

性能优化

  1. 调整 Sentinel 配置

    • 根据实际情况调整 down-after-millisecondsfailover-timeout
    • 调整 parallel-syncs 值,优化故障转移后的同步速度
  2. Redis 配置优化

    • 优化主从复制配置
    • 调整持久化策略,平衡性能和安全性
    • 优化内存使用,设置合理的 maxmemorymaxmemory-policy
  3. 系统优化

    • 优化 Linux 内核参数
    • 调整文件描述符限制
    • 优化网络参数

安全性优化

  1. 访问控制

    • 配置防火墙,限制 Redis 和 Sentinel 访问
    • 使用密码保护 Redis 和 Sentinel
    • 考虑使用 TLS 加密通信
  2. 审计

    • 启用 Redis 慢查询日志
    • 监控异常命令
    • 定期检查 Redis 配置和数据
  3. 备份策略

    • 制定合理的备份策略
    • 定期测试备份恢复
    • 考虑异地备份

监控优化

  1. 监控指标

    • 监控 Sentinel 节点状态
    • 监控主从复制状态
    • 监控故障转移事件
    • 监控客户端连接数和请求量
  2. 告警设置

    • 设置合适的告警阈值
    • 配置多渠道告警(邮件、短信、企业微信等)
    • 建立完善的告警响应流程
  3. 可视化

    • 使用 Grafana 等工具可视化监控数据
    • 建立监控面板,展示关键指标
    • 定期分析监控数据,发现潜在问题

常见问题(FAQ)

Q1: 迁移过程中会导致服务中断吗?

A1: 迁移过程中,主从架构仍然正常运行,Sentinel 节点的部署和配置不会影响现有服务。客户端迁移过程中,可能会有短暂的连接切换,但使用支持 Sentinel 协议的客户端可以自动处理这种切换,不会导致服务中断。

Q2: 可以在现有主从架构上直接部署 Sentinel 吗?

A2: 是的,可以在现有主从架构上直接部署 Sentinel 节点,不需要停止或修改现有的 Redis 节点。Sentinel 会自动发现和监控现有的主从架构。

Q3: Sentinel 节点需要多少资源?

A3: Sentinel 节点占用的资源较少,通常只需要几百 MB 的内存和少量 CPU 资源。建议为每个 Sentinel 节点分配至少 512 MB 内存和 1 个 CPU 核心。

Q4: 如何选择 Sentinel 节点的数量?

A4: 建议部署 3 个或 5 个 Sentinel 节点。奇数个节点可以避免脑裂问题,3 个节点是最常用的配置,5 个节点可以提供更高的可靠性。

Q5: 迁移后如何回滚?

A5: 如果迁移过程中出现问题,可以通过以下步骤回滚:

  1. 停止所有 Sentinel 节点
  2. 将客户端配置改回直接连接主节点
  3. 恢复原有的主从架构配置

Q6: 如何测试 Sentinel 的自动故障转移功能?

A6: 可以通过以下方式测试:

  1. 手动停止主节点 Redis 服务
  2. 监控 Sentinel 日志,观察故障转移过程
  3. 验证从节点是否被提升为主节点
  4. 验证客户端是否自动连接到新的主节点

Q7: 主从复制和 Sentinel 有什么区别?

A7: 主从复制是一种数据冗余机制,通过将主节点的数据复制到从节点实现数据备份。Sentinel 是一种高可用机制,在主从复制的基础上,添加了自动故障转移功能,可以在主节点故障时自动将从节点提升为主节点。

Q8: 可以使用 Docker 部署 Sentinel 吗?

A8: 是的,可以使用 Docker 部署 Sentinel 节点。需要注意的是,确保 Docker 容器之间网络通畅,并且配置文件正确映射到容器内部。

Q9: 如何监控 Sentinel 集群?

A9: 可以使用以下方式监控 Sentinel 集群:

  1. 使用 Redis 内置的 info sentinel 命令获取 Sentinel 状态
  2. 监控 Sentinel 日志
  3. 使用第三方监控工具(如 Prometheus + Grafana)
  4. 使用 RedisInsight 等图形化工具

Q10: 迁移后需要注意什么?

A10: 迁移后需要注意以下几点:

  1. 定期监控 Sentinel 集群状态
  2. 定期进行故障转移演练
  3. 优化配置参数,提高系统性能和可靠性
  4. 关注 Redis 和 Sentinel 的版本更新,及时升级
  5. 建立完善的监控和告警机制