获得直连地址后,您可以绕过代理,用直连模式访问云数据库Redis集群实例,缩短Redis服务的响应时间。本章节以使用Jedis和PhpRedis客户端为例,介绍了直连访问的注意事项和方法。
前提条件
- 开通直连访问。
- 将客户端地址加入Redis白名单。
- 使用Jedis、PhpRedis等支持Redis Cluster的客户端。
- Redis客户端所在的ECS与目标Redis实例在同一VPC网络。
背景信息

注意事项
- 由于部署架构的不同,相对标准架构来说,集群架构的实例在原生Redis命令的支持上有一定的区别(例如不支持SWAPDB命令、Lua存在使用限制等)。更多信息,请参见集群架构实例的命令限制。
- 直连模式下,如果执行变更实例配置,系统会采用Slot(槽)迁移的方式来完成,此场景下,客户端可能因访问到正在迁移的Slot而提示
MOVED
、TRYAGAIN
等错误信息。如需确保请求的成功执行,请为客户端设计重试机制。更多信息,请参见Redis客户端重试指南。 - 直连模式支持使用SELECT命令切换DB,但部分Redis Cluster客户端(例如stackExchange.redis)不支持SELECT命令,如果使用该类客户端则只能使用DB0。
- 直连地址仅支持通过阿里云内网访问,且同时支持VPC免密和账号密码认证。
Jedis连接代码
import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisCluster; import redis.clients.jedis.JedisPoolConfig; import java.util.HashSet; import java.util.Set; public class DirectTest { private static final int DEFAULT_TIMEOUT = 2000; private static final int DEFAULT_REDIRECTIONS = 5; private static final JedisPoolConfig DEFAULT_CONFIG = new JedisPoolConfig(); public static void main(String args[]){ // 开通直连访问时申请到的直连地址 String host = "r-bp1xxxxxxxxxxxx.redis.rds.aliyuncs.com"; int port = 6379; String password = "xxxx"; Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>(); jedisClusterNode.add(new HostAndPort(host, port)); JedisCluster jc = new JedisCluster(jedisClusterNode, DEFAULT_TIMEOUT, DEFAULT_TIMEOUT, DEFAULT_REDIRECTIONS,password, "clientName", DEFAULT_CONFIG); jc.set("key","value"); jc.get("key"); jc.close(); } }
import redis.clients.jedis.*; import java.util.HashSet; import java.util.Set; public class main { private static final int DEFAULT_TIMEOUT = 2000; private static final int DEFAULT_REDIRECTIONS = 5; private static final JedisPoolConfig DEFAULT_CONFIG = new JedisPoolConfig(); public static void main(String args[]){ JedisPoolConfig config = new JedisPoolConfig(); // 最大空闲连接数,由于直连模式为客户端直接连接某个数据库分片,需要保证:业务机器数 * MaxTotal < 单个数据库分片的最大连接数。 // 其中社区版单个分片的最大连接数为10,000,企业版单个分片的最大连接数为30,000。 config.setMaxTotal(30); // 最大空闲连接数, 根据业务需要设置。 config.setMaxIdle(20); config.setTestOnBorrow(false); config.setTestOnReturn(false); // 开通直连访问时申请到的直连地址 String host = "r-bp1xxxxxxxxxxxx.redis.rds.aliyuncs.com"; int port = 6379; // 实例的密码 String password = "xxxxx"; Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>(); jedisClusterNode.add(new HostAndPort(host, port)); JedisCluster jc = new JedisCluster(jedisClusterNode, DEFAULT_TIMEOUT, DEFAULT_TIMEOUT, DEFAULT_REDIRECTIONS,password, "clientName", config); } }
说明 Jedis使用说明请参见官方文档。
PhpRedis连接代码示例
<?php // 直连地址和连接端口 $array = ['r-bp1xxxxxxxxxxxx.redis.rds.aliyuncs.com:6379']; // 连接密码 $pwd = "xxxx"; // 使用密码连接集群 $obj_cluster = new RedisCluster(NULL, $array, 1.5, 1.5, true, $pwd); // 输出连接结果 var_dump($obj_cluster); if ($obj_cluster->set("foo", "bar") == false) { die($obj_cluster->getLastError()); } $value = $obj_cluster->get("foo"); echo $value; ?>
说明 PhpRedis使用说明请参见官方文档。
Spring Data Redis代码示例
@Bean JedisConnectionFactory redisConnectionFactory() { List<String> clusterNodes = Arrays.asList("host1:port1", "host2:port2", "host3:port3"); RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(clusterNodes); redisClusterConfiguration.setPassword("xxx"); JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); // 最大空闲连接数,由于直连模式为客户端直接连接某个数据库分片,需要保证:业务机器数 * MaxTotal < 单个数据库分片的最大连接数。 // 其中社区版单个分片的最大连接数为10,000,企业版单个分片的最大连接数为30,000。 jedisPoolConfig.setMaxTotal(30); // 最大空闲连接数, 根据业务需要设置。 jedisPoolConfig.setMaxIdle(20); // 关闭 testOn[Borrow|Return],防止产生额外的 PING jedisPoolConfig.setTestOnBorrow(false); jedisPoolConfig.setTestOnReturn(false); return new JedisConnectionFactory(redisClusterConfiguration, jedisPoolConfig); }
@Bean public LettuceConnectionFactory redisConnectionFactory() { List<String> clusterNodes = Arrays.asList("host1:port1", "host2:port2", "host3:port3"); RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(clusterNodes); redisClusterConfiguration.setPassword("xxx"); ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder() .enablePeriodicRefresh(Duration.ofSeconds(15)) // 集群拓扑刷新周期,建议为15s,若配置的值太小会产生大量的Cluster Nodes调用,影响性能。 .dynamicRefreshSources(false) // 是否采用使用Cluster Nodes中获取的IP用来作为集群拓扑刷新的调用节点。连接云数据库Redis实例时,需要配置为false。 .enableAllAdaptiveRefreshTriggers() // 开启集群拓扑刷新,包含遇到MOVED等消息就自动刷新集群一次。 .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(15)).build(); // 为防止集群拓扑刷新频率过高,此参数只允许在对应时间内产生一次拓扑刷新。 LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder(). clientOptions(ClusterClientOptions.builder() .validateClusterNodeMembership(false) .topologyRefreshOptions(topologyRefreshOptions).build()).build(); return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration); }
说明 Spring Data Redis使用说明请参见Spring。
Lettuce连接代码示例
Lettuce支持完整Redis API的同步和异步通信使用。由于Lettuce客户端在请求多次请求超时后,不再自动重连,当云数据库Redis因故障等因素导致代理或者数据库节点发生切换时,可能出现连接超时导致无法重连。为避免此类风险,推荐您使用其他客户端。
public class ClusterDemo { public static void main(String[] args) throws Exception { String host = "r-bp1xxxxxxxxxxxx.redis.rds.aliyuncs.com"; int port = 30001; String password = "xxxx"; RedisURI redisURI = RedisURI.Builder.redis(host) .withPort(port) .withPassword(password) .build(); ClusterTopologyRefreshOptions refreshOptions = ClusterTopologyRefreshOptions.builder() .enablePeriodicRefresh(Duration.ofSeconds(15)) // 集群拓扑刷新周期,建议为15s,若配置的值太小会产生大量的Cluster Nodes调用,影响性能。 .dynamicRefreshSources(false) // 是否采用使用Cluster Nodes中获取的IP用来作为集群拓扑刷新的调用节点。连接云数据库Redis实例时,需要配置为false。 .enableAllAdaptiveRefreshTriggers() // 开启集群拓扑刷新,包含遇到MOVED等消息就自动刷新集群一次。 .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(15)).build(); // 为防止集群拓扑刷新频率过高,此参数只允许在对应时间内产生一次拓扑刷新。 RedisClusterClient redisClient = RedisClusterClient.create(redisURI); redisClient.setOptions(ClusterClientOptions.builder() .socketOptions(SocketOptions.builder() .keepAlive(true) // 开启keepAlive参数。 .build()) .validateClusterNodeMembership(false) .topologyRefreshOptions(refreshOptions).build()); StatefulRedisClusterConnection<String, String> connection = redisClient.connect(); connection.sync().set("key", "value"); } }
说明 Lettuce使用说明请参见Lettuce。
常见问题
- Q:通过Lettuce连接Redis时,报错
Connection to xxx not allowed. This partition is not known in the cluster view.
。A:请按照上述Lettuce连接代码示例配置refreshOptions选项。