导读:本期聚焦于菲律宾程序员创作的《Redis Sentinel客户端如何正确配置?高可用集群接入实战指南》,敬请观看详情。主从架构下的Redis一旦发生主节点故障,客户端如果还写死连接旧的master地址,整个服务就会陷入不可用状态。Sentinel机制的出现正是为了解决这个问题,但不少人在接入时发现客户端连不上、故障切换后不生效,甚至读写分离失效。本文围绕Redis Sentinel客户端配置展开,先讲清Sentinel的工作原理和客户端需要感知什么信息,再分别演示Java的Jedis与Lettuce、Go的go-redis以及Python的redis-py等主流客户端的完整配置代码,最后分析连接超时、sentinel认证、故障切换感知延迟等常见坑点,帮助你把高可用方案真正落地。

Redis Sentinel是官方提供的高可用方案,它通过一组独立的Sentinel进程监控主从节点,在master不可用时自动完成故障检测、选举和切换。但很多人忽略了一点:Sentinel只负责服务端的切换,客户端必须以正确的姿势接入,才能真正享受高可用能力。如果客户端把连接地址写死成master的IP和端口,那么切换发生的那一刻,所有写请求都会打到一台已经降级为slave(甚至已经下线)的机器上,业务直接报错。这篇文章就来聊聊客户端侧到底该怎么配置。

Redis Sentinel客户端如何正确配置?高可用集群接入实战指南

一、先搞清楚Sentinel模式下客户端的工作机制

在传统主从模式下,客户端只需要知道master的地址。而在Sentinel架构中,客户端的连接流程发生了本质变化:它先连接Sentinel节点(注意是Sentinel,不是数据节点),通过执行SENTINEL get-master-addr-by-name mymaster命令获取当前master的真实地址,然后再与这个master建立连接进行读写。这个过程可以理解为“问路”——Sentinel知道谁是当前的主节点,客户端每次初始化时都要先问一遍。

一个容易被忽略的细节是:客户端需要订阅Sentinel的+switch-master频道。当故障切换完成后,Sentinel会向该频道发布消息,告知新的master地址。订阅了这个频道的客户端能在秒级感知到切换并重建连接池;而没有订阅机制的客户端只能依赖连接报错后的重试,感知速度会慢很多,期间还会产生大量失败请求。成熟的客户端库(如Lettuce、go-redis)内部都实现了这套订阅逻辑,这也是为什么强烈建议使用官方或社区维护完善的库,而不是自己手写Socket连接。

另外要理解Sentinel的判定条件。默认配置下,一个Sentinel需要down-after-milliseconds时间内连续收不到master响应才会标记其主观下线,再需要达到quorum个Sentinel同意才会判定客观下线,之后还要经过选举和切换流程。整个过程通常需要十几秒到几十秒,客户端的重试策略必须覆盖这个时间窗口,否则切换期间的用户请求会大量失败。

二、主流客户端的配置代码示例

1. Java环境:Jedis与Lettuce

Jedis是老牌客户端,配置Sentinel时通过JedisSentinelPool完成,需要传入Sentinel节点集合和master名称:

Set<String> sentinels = new HashSet<>();
sentinels.add("192.168.1.10:26379");
sentinels.add("192.168.1.11:26379");
sentinels.add("192.168.1.12:26379");

String masterName = "mymaster";
String password = "yourPassword";

JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinels,
        new JedisPoolConfig(), 2000, 2000, password);
try (Jedis jedis = pool.getResource()) {
    jedis.set("demo:key", "hello");
    System.out.println(jedis.get("demo:key"));
}

注意这里的地址必须是Sentinel的地址,而不是master地址,这是新手最常见的错误。JedisSentinelPool会从Sentinel查询master地址并维护连接池,切换时会自动刷新。

如果用的是Spring Boot加Lettuce(默认组合),配置更简洁,直接在application.yml中写:

spring:
  redis:
    password: yourPassword
    sentinel:
      master: mymaster
      nodes:
        - 192.168.1.10:26379
        - 192.168.1.11:26379
        - 192.168.1.12:26379
    timeout: 2000

Lettuce基于Netty实现,连接是线程安全的单个共享连接,并且内置了对Sentinel事件频道的订阅,故障切换的感知速度比Jedis更快。生产环境一般推荐这个组合。

2. Go环境:go-redis

go-redis的v9版本对Sentinel支持很完善,配置时使用FailoverClient模式:

package main

import (
	"context"
	"fmt"

	"github.com/redis/go-redis/v9"
)

func main() {
	rdb := redis.NewFailoverClient(&redis.FailoverOptions{
		MasterName:    "mymaster",
		SentinelAddrs: []string{"192.168.1.10:26379", "192.168.1.11:26379", "192.168.1.12:26379"},
		Password:      "yourPassword",
		DialTimeout:   3 * time.Second,
		ReadTimeout:   2 * time.Second,
		MaxRetries:    3,
	})
	val, err := rdb.Get(context.Background(), "demo:key").Result()
	fmt.Println(val, err)
}

如果还需要读写分离,把NewFailoverClient换成NewFailoverClusterClient,它会自动发现slave节点并将读命令路由过去。要注意写命令依然只会发往master,不要指望读写分离能分担写压力。

3. Python环境:redis-py

redis-py从3.x开始推荐使用redis.asyncio或同步客户端的Sentinel封装:

from redis.sentinel import Sentinel

sentinel = Sentinel(
    [("192.168.1.10", 26379), ("192.168.1.11", 26379), ("192.168.1.12", 26379)],
    socket_timeout=2,
)

master = sentinel.master_for("mymaster", password="yourPassword")
master.set("demo:key", "hello")

slave = sentinel.slave_for("mymaster", password="yourPassword")
print(slave.get("demo:key"))

这里的master_forslave_for返回的客户端会在每次操作前检查连接可用性,故障切换后能自动指向新的master。不过要注意slave_for读到的数据可能有复制延迟,对一致性敏感的读操作仍然走master更稳妥。

三、配置中的常见坑与排查思路

1. Sentinel自身设置了密码怎么办

较新版本的Redis支持给Sentinel进程单独设置密码(配置项为requirepass),这时候客户端连接数据节点和连接Sentinel需要两个不同的密码。以go-redis为例,数据节点密码用Password字段,Sentinel密码用SentinelPassword字段。Jedis方面,需要在构造函数中分别传入这两个参数,版本太老的Jedis不支持这个特性,遇到认证失败又确认密码正确时,先升级客户端版本再排查。

2. 连接超时与重试策略要覆盖切换窗口

故障切换完成前,master地址实际上是失效的。客户端的超时设置过短会导致大量请求快速失败,设置过长又会让用户等待过久。实践经验是:连接超时控制在1到3秒,命令超时1到2秒,并配合3次左右的指数退避重试。这样单个请求最多重试几秒,正好能扛过切换窗口。同时在业务代码里,对写操作要做好幂等设计,因为重试可能导致同一条数据被写入两次。

3. 网络与防火墙问题

Sentinel默认端口是26379,客户端部署环境必须能访问所有Sentinel节点的26379端口以及数据节点的6379端口。有一个隐蔽的坑:Sentinel会在故障切换后主动用SENTINEL announce-ip或自动发现的地址广播新的master地址,如果Redis服务器有多块网卡,它可能广播一个客户端无法路由的内网地址。解决办法是在redis.conf中显式配置replica-announce-ipreplica-announce-port,或者给Sentinel配置announce-ip,确保广播出去的地址客户端可达。

4. 验证配置是否生效

配置完成后,建议做一次切换演练:用redis-cli -p 6379 shutdown nosave直接关掉master,观察客户端日志中是否出现重连记录,业务是否在十几秒后自动恢复。也可以通过redis-cli -p 26379 sentinel masters查看Sentinel记录的master地址是否已经更新。演练通过的高可用配置才算真正可用,否则上线后第一次故障就是事故现场。

四、几点最佳实践总结

第一,Sentinel节点至少部署3个且分布在不同的物理机或可用区,quorum一般设为节点数的一半加一,避免脑裂。第二,客户端配置里写Sentinel地址列表而非master地址,并且把所有Sentinel都列上,单个Sentinel挂掉不影响客户端发现master。第三,读写分离要谨慎,复制延迟在没有强一致要求的场景(如缓存、统计)下才适合走slave。第四,监控不能少,对sdownodown+switch-master等事件配置告警,切换发生时运维能第一时间知道,而不是等用户投诉才发现。把这些细节都处理好,Sentinel方案才能真正为业务提供稳定的高可用保障。

Redis Sentinel客户端配置高可用修改时间:2026-09-16 10:06:54

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。