资讯详情

资讯详情

Redis Sentinel高可用机制详解与实践指南

1. Redis Sentinel 机制的核心价值与适用场景Redis Sentinel哨兵是Redis官方提供的高可用性解决方案它解决了单点Redis实例在故障时无法自动恢复的核心痛点。我在实际生产环境中部署过数十套Sentinel系统深刻体会到它对业务连续性的保障价值。想象这样一个场景你的电商平台正在举行秒杀活动所有库存数据和用户抢购记录都存储在Redis主节点上。凌晨3点主节点突然宕机如果没有SentinelDBA需要手动介入执行故障转移从发现到恢复至少需要15分钟这意味着数百万的GMV损失。而Sentinel可以在30秒内完成新主节点的选举和流量切换整个过程对业务透明。Sentinel机制主要实现三大核心功能监控持续检查主从节点的健康状态通知通过API向运维系统发送告警自动故障转移主节点不可用时提升从节点为新主节点并重新配置其他从节点重要提示Sentinel本身也需要以集群方式部署通常建议至少3个节点部署在不同物理机上防止自身单点故障。2. Sentinel 集群的底层工作原理2.1 监控阶段的实现细节Sentinel节点每秒向所有主从节点发送PING命令通过响应判断节点状态。这里有个关键参数down-after-milliseconds默认30秒当连续超过该时间未收到有效回复时Sentinel会将该节点标记为主观下线(SDOWN)。我在阿里云环境中曾遇到一个典型案例某次网络抖动导致Sentinel与Redis节点间的PING包延迟达到35秒触发了误判。此时需要调整down-after-milliseconds为更合理的值如60秒这个参数需要根据实际网络状况谨慎设置。2.2 故障判定与客观下线当某个Sentinel认为主节点不可用时它会向其他Sentinel节点发送SENTINEL is-master-down-by-addr命令进行确认。只有当quorum数量的Sentinel通常配置为Sentinel总数/2 1都认为主节点不可用时才会触发客观下线(ODOWN)。下表展示了不同Sentinel集群规模下的推荐quorum设置Sentinel节点数推荐quorum值容错能力11无321节点故障532节点故障743节点故障2.3 领导者选举与故障转移进入ODOWN状态后Sentinel集群会通过Raft算法选举出一个领导者来执行故障转移。选举依据包括先到先得最先检测到ODOWN的Sentinel有更高优先级配置纪元(configuration epoch)每次故障转移都会递增这个值运行ID当其他条件相同时运行ID较小的Sentinel获胜选举出的领导者会执行以下关键操作从存活的从节点中选择一个作为新主节点向该从节点发送SLAVEOF NO ONE命令通过PUBLISH命令通知其他从节点复制新主节点更新客户端可见的主节点地址3. 生产级Sentinel集群搭建指南3.1 基础环境准备建议使用至少3台物理机或独立VM避免所有Sentinel部署在同一台宿主机上。以下是我的标准配置清单# 系统参数调整所有节点 echo vm.overcommit_memory 1 /etc/sysctl.conf echo net.core.somaxconn 1024 /etc/sysctl.conf sysctl -p # 创建专用用户和目录 useradd -r -s /sbin/nologin redis mkdir -p /var/lib/redis/{data,log} chown -R redis:redis /var/lib/redis3.2 Redis主从配置主节点redis.conf关键配置bind 0.0.0.0 port 6379 daemonize yes pidfile /var/run/redis_6379.pid logfile /var/lib/redis/log/redis.log dir /var/lib/redis/data requirepass your_strong_password masterauth your_strong_password # 从节点访问主节点的密码从节点额外配置replicaof master-ip 6379 replica-read-only yes3.3 Sentinel节点配置每个Sentinel节点的sentinel.conf需要包含port 26379 daemonize yes logfile /var/lib/redis/log/sentinel.log sentinel monitor mymaster master-ip 6379 2 sentinel auth-pass mymaster your_strong_password sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 60000 sentinel parallel-syncs mymaster 1关键参数说明down-after-milliseconds建议设置为网络RTT的3倍parallel-syncs故障转移时允许同时同步的从节点数大数据量环境下建议设为1failover-timeout控制故障转移各阶段的超时时间3.4 集群启动与验证启动顺序非常重要先启动主节点启动所有从节点最后启动Sentinel节点验证命令示例# 查看主从状态 redis-cli -h master-ip info replication # 查看Sentinel监控状态 redis-cli -h sentinel-ip -p 26379 sentinel master mymaster4. 实战故障转移测试与问题排查4.1 模拟主节点故障我常用的几种测试方法暴力测试直接kill -9主节点进程网络隔离用iptables阻断主节点流量iptables -A INPUT -p tcp --dport 6379 -j DROP服务降级通过CONFIG SET设置超时参数redis-cli -h master-ip CONFIG SET timeout 14.2 转移过程监控通过以下命令观察转移过程# 实时查看Sentinel日志 tail -f /var/lib/redis/log/sentinel.log # 观察主从切换状态 watch -n 1 redis-cli -h sentinel-ip -p 26379 sentinel get-master-addr-by-name mymaster典型成功日志示例sdown master mymaster 192.168.1.10 6379 # 主观下线 odown master mymaster 192.168.1.10 6379 #quorum 2/2 # 客观下线 try-failover master mymaster 192.168.1.10 6379 # 尝试故障转移 elected-leader master mymaster 192.168.1.10 6379 # 选举领导者 failover-state-select-slave master mymaster 192.168.1.10 6379 # 选择从节点 selected-slave slave 192.168.1.11:6379 192.168.1.11 6379 mymaster 192.168.1.10 6379 # 选中新主 failover-state-send-slaveof-noone slave 192.168.1.11:6379 192.168.1.11 6379 mymaster 192.168.1.10 6379 # 提升为主4.3 常见问题与解决方案问题1脑裂现象现象原主节点恢复后出现两个主节点 解决方法# 手动降级旧主节点 redis-cli -h old-master-ip SLAVEOF new-master-ip 6379问题2故障转移超时可能原因failover-timeout设置过短从节点数据同步缓慢 优化方案sentinel failover-timeout mymaster 120000 # 适当调大 sentinel client-reconfig-script mymaster /path/to/notify.sh # 添加通知脚本问题3客户端连接失败典型日志Error: Connection reset by peer解决方案 使用支持Sentinel的客户端连接池如JedisJedisPoolConfig poolConfig new JedisPoolConfig(); JedisSentinelPool pool new JedisSentinelPool(mymaster, Sets.newHashSet(sentinel1:26379, sentinel2:26379, sentinel3:26379), poolConfig, your_strong_password);5. 高级配置与性能优化5.1 网络拓扑优化对于跨机房部署建议采用机房A主节点 1个从节点 1个Sentinel 机房B1个从节点 1个Sentinel 机房C1个Sentinel配置示例sentinel monitor mymaster master-ip 6379 2 sentinel auth-pass mymaster your_strong_password sentinel down-after-milliseconds mymaster 10000 # 跨机房建议增大5.2 持久化策略配合推荐配置主节点关闭AOF仅使用RDBsave 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error no # 避免bgsave失败导致写阻塞从节点开启AOFappendonly yes appendfsync everysec no-appendfsync-on-rewrite yes5.3 监控指标与告警关键监控项sentinel_known_slaves从节点数量sentinel_known_sentinelsSentinel节点数量master_link_status主从连接状态Prometheus配置示例- job_name: redis_sentinel static_configs: - targets: [sentinel1:26379, sentinel2:26379, sentinel3:26379] metrics_path: /metrics6. 客户端接入最佳实践6.1 连接池配置要点Java(Jedis)示例JedisPoolConfig config new JedisPoolConfig(); config.setMaxTotal(100); config.setMaxIdle(20); config.setMinIdle(5); config.setTestOnBorrow(true); config.setTestOnReturn(true); SetString sentinels new HashSet(); sentinels.add(sentinel1:26379); sentinels.add(sentinel2:26379); JedisSentinelPool pool new JedisSentinelPool(mymaster, sentinels, config, 2000, password);关键参数说明testOnBorrow从池中获取连接时进行健康检查maxWaitMillis获取连接的最大等待时间连接验证需要放在finally块中确保释放6.2 多语言客户端支持Python (redis-py)from redis.sentinel import Sentinel sentinel Sentinel([(sentinel1, 26379), (sentinel2, 26379)], socket_timeout0.1) master sentinel.master_for(mymaster, passwordpassword) slave sentinel.slave_for(mymaster, passwordpassword)Go (go-redis)import github.com/go-redis/redis/v8 sentinel : redis.NewSentinelClient(redis.Options{ Addrs: []string{sentinel1:26379, sentinel2:26379}, }) client : redis.NewFailoverClient(redis.FailoverOptions{ MasterName: mymaster, SentinelAddrs: []string{sentinel1:26379, sentinel2:26379}, Password: password, })6.3 重试策略设计建议采用指数退避算法long retryInterval 100; // 初始间隔100ms long maxInterval 5000; // 最大间隔5s int maxAttempts 5; // 最大尝试次数 for (int i 0; i maxAttempts; i) { try (Jedis jedis pool.getResource()) { jedis.set(key, value); break; } catch (Exception e) { if (i maxAttempts - 1) throw e; Thread.sleep(Math.min(retryInterval * (1 i), maxInterval)); } }在实际业务中我们会将这种重试逻辑封装成统一的Redis访问工具类配合熔断机制如Hystrix使用确保在Redis集群完全不可用时不会拖垮整个应用。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →