使用 sentinel 模式连接
所有文档
menu

云数据库 Redis

使用 sentinel 模式连接

产品详情自助选购

简介

百度智能云数据库 Redis 支持基于 sentinel 模式连接,本文档将介绍如何使用 sentinel 模式连接到 云数据库 Redis 集群。

背景信息

使用 sentinel 模式连接集群时,客户端先从 sentinel 上获取 Redis 节点的地址,然后连接 Redis 节点,流程如下:

image.png

上图中,客户端先给 sentinel 节点发送 sentinel get-master-by-name 获取到对应 master 的地址,而后连接 master 并执行读写命令。

百度智能云数据库 Redis 单机版和集群版均提供了 sentinel 系列的命令,将自己伪装为一个 sentinel 节点,此前使用 sentinel 模式的客户端,无需变更代码即可接入百度云Redis集群。其原理如下图所示:

image.png

上图中 Redis 节点兼任 sentinel 节点的功能,因此在使用 sentinel 模式时接入云数据库 Redis 时,需要明白 sentinel 节点和 Redis 节点实际上是同一个。

主流客户端示例

下面介绍各主流客户端使用 sentinel 模式接入的方式。

go-redis

redis.NewSentinelClient用来创建一个连接到 sentinel 节点的客户端,可以直接给 sentinel 节点发送命令。

sentinel := redis.NewSentinelClient(&redis.Options{
    Addr:     "127.0.0.1:6379",
    Password: "sentinel-password",
})
sentinel.GetMasterAddrByName(ctx, "master-name")

通常我们需要使用 redis.NewFailoverClient ,这个客户端会从 sentinel 中或许 redis 节点的信息,然后创建连接到 redis 节点的客户端,用户可以直接发送命令读写 redis。

cli := redis.NewFailoverClient(&redis.FailoverOptions{
    MasterName:       "master-name",
    SentinelAddrs:    []string{"127.0.0.1:26379"},
    Password:         "redis-password",
    SentinelPassword: "sentinel-password",
})
client := cli.Get(ctx, "key")

Jedis

String host = "redis.*******.scs.bj.baidubce.com"int port = 6379;  
String password = "*****"; 
String masterName = "master-name";
JedisClientConfig clientConfig = DefaultJedisClientConfig.builder().password(password).build();
JedisClientConfig sentinelConfig = DefaultJedisClientConfig.builder().password(password).build();
Set<HostAndPort> sentinels = new HashSet<HostAndPort>();
sentinels.add(HostAndPort.from(host + ":" + Integer.toString(port)));
JedisPoolConfig poolConfig = new JedisPoolConfig();
JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinels, poolConfig, clientConfig, sentinelConfig);
Jedis jedis = pool.getResource();
jedis.set("foo", "bar");

这里实际是将 redis 实例作为了 sentinel 节点,因此 sentinel 的地址和密码和云数据库 Redis 集群的地址是一样的。 注意:

  • JedisSentinelPool 有多个构造函数,如果集群有密码,在传入密码的时候,需要同时传入 sentinel-password 和 password。
  • 使用 sentinel 模式时,如果出现如下错误,这是正常的,可以将 JedisClientConfig的 blockingSocketTimeoutMillis设置为一个很大的值即可。
ERROR 2024-05-30 11:31:01,604 redis.clients.jedis.JedisSentinelPool$MasterListener: Lost connection to Sentinel at 127.0.0.1:26379. Sleeping 5000ms and retrying.
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
	at redis.clients.jedis.util.RedisInputStream.ensureFill(RedisInputStream.java:251)
	at redis.clients.jedis.util.RedisInputStream.readByte(RedisInputStream.java:47)
	at redis.clients.jedis.Protocol.process(Protocol.java:135)
	at redis.clients.jedis.Protocol.read(Protocol.java:221)
	at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:350)
	at redis.clients.jedis.Connection.getUnflushedObject(Connection.java:316)
	at redis.clients.jedis.JedisPubSubBase.process(JedisPubSubBase.java:115)
	at redis.clients.jedis.JedisPubSubBase.proceed(JedisPubSubBase.java:92)
	at redis.clients.jedis.Jedis.subscribe(Jedis.java:7941)
	at redis.clients.jedis.JedisSentinelPool$MasterListener.run(JedisSentinelPool.java:377)

这个错误的原因是,sentinel 客户端启动后会发送一个 subscribe 给 redis 实例,但默认阻塞命令的超时时间的 5 秒,而 subscribe 本就需要阻塞等待后端响应,所以每隔 5 秒就会断开一次。而这个 5 秒是由 JedisClientConfig的blockingSocketTimeoutMillis 参数决定的。

redis-py

host = "redis.*******.scs.bj.baidubce.com"
port = 6379  
password = "*****"
sentinel_password = password
# 这里 password 是 Redis 节点的密码,sentinel_kwargs 中的 password 是 sentinel 的密码
sentinel = Sentinel(host, port, password=password, sentinel_kwargs={'password': sentinel_password}) 

若访问不通时,请自查是否漏掉了 sentinel password,形如下面这样的配置是不对的:

sentinel = Sentinel(..., password='123456'}) 
上一篇
查看连接地址
下一篇
使用单机模式连接