#如何访问集群实例
本指南演示如何使用行业标准的客户端库建立到 Redis 集群模式实例的连接。示例涵盖 go-redis、Jedis、Lettuce 和 Redisson 的配置细节。有关更多客户端选项,请参阅 使用 Redis client API libraries 连接。
#认证要求
Redis 集群模式实例支持以下认证选项:
- 密码认证:当配置了密码时,所有客户端连接都必须提供有效凭据
- 无密码访问:如果在实例创建期间禁用了 Set Password 选项,客户端可在无需认证的情况下连接
安全最佳实践
对于生产环境,强烈建议启用密码认证以保护您的数据。有关配置和维护安全凭据的详细说明,请参阅 用户管理。
#连接端点参考
#内部集群访问
对于部署在同一 Kubernetes 集群中的应用,可通过 Access Method 选项卡下 Access within the Cluster 部分获取内部访问端点。
| 参数 | 描述 |
|---|---|
| Connection Address | 每个 Redis 集群模式分片的 Kubernetes 服务名称和端口组合 |
#外部集群访问
对于从 Kubernetes 环境外部连接的应用,如果在实例创建期间进行了配置,则可使用外部访问端点。这些端点可在 Access Method 选项卡下 Access from outside the Cluster 部分找到。
| 端点类型 | 描述 |
|---|---|
| Shard Address | Redis 集群模式中分片的 pod 的外部 IP 地址和端口,用于从 Kubernetes 网络外部建立连接 |
#交互式调试
对于管理操作和故障排查,Redis CLI 可直接访问集群节点:
-
在实例详情页中打开 Terminal Console
-
使用支持集群的客户端模式连接到任意节点:
redis-cli -c -h <internal-routing-ip> -p 6379
以下是一个演示基于 slot 重定向的调试会话示例:
192.168.0.10:6379> set a 1
-> Redirected to slot [15495] located at 192.168.0.10:6379
OK
192.168.0.10:6379> get a
"1"
192.168.0.10:6379>-c 标志可启用自动跟随 MOVED 和 ASK 重定向,这在使用 Redis 集群模式时非常重要。
#客户端集成示例
以下示例演示使用各种客户端库连接到 Redis 集群模式实例的最佳实践。
go-redis
Jedis
Lettuce
Redisson
package main
import (
"context"
"fmt"
"time"
// It is recommended to periodically upgrade to the latest version of the client for the latest bug fixes.
"github.com/redis/go-redis/v9"
)
func main() {
client := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{"<address>"},
Password: "<password>",
OnConnect: func(ctx context.Context, conn *redis.Conn) error {
ctx, cancel := context.WithTimeout(ctx, 500*time.Millisecond)
defer cancel()
return conn.Ping(ctx).Err()
},
// Client name for tracking purposes
ClientName: "go-demo",
// Use Context for timeout control
ContextTimeoutEnabled: true,
// Maximum number of redirects in case of MOVED or ASK
MaxRedirects: 3,
// Maximum number of retries
MaxRetries: 3,
// Minimum retry backoff
MinRetryBackoff: 20 * time.Millisecond,
// Maximum retry backoff
MaxRetryBackoff: 200 * time.Millisecond,
// Connection timeout
DialTimeout: 3 * time.Second,
// Read timeout
ReadTimeout: 5 * time.Second,
// Write timeout
WriteTimeout: 10 * time.Second,
// Connection pool size for each node
PoolSize: 100,
// Maximum wait time for available connections in the pool
PoolTimeout: time.Second,
// Minimum number of idle connections for each node
MinIdleConns: 5,
// Maximum number of idle connections for each node
MaxIdleConns: 10,
// Maximum number of active connections for each node
MaxActiveConns: 100,
// Maximum idle time for connections
ConnMaxIdleTime: time.Minute * 5,
})
defer client.Close()
if val, err := client.Get(context.TODO(), "test").Result(); err != nil {
panic(err)
} else {
fmt.Println(val)
}
}有关更详细的配置,请参阅 Community Documentation
package io.alauda.demo.redis;
import redis.clients.jedis.ConnectionPoolConfig;
import redis.clients.jedis.JedisClientConfig;
import redis.clients.jedis.DefaultJedisClientConfig;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.HostAndPort;
import java.time.Duration;
import java.util.Set;
import java.util.HashSet;
public class Main {
public static void main(String []args) {
// Configure Jedis pool options
ConnectionPoolConfig poolConfig = new ConnectionPoolConfig();
// Set connection pool size; -1 means unlimited. New connections will fail if this limit is exceeded.
poolConfig.setMaxTotal(200);
// Set maximum idle connections; idle connections exceeding this limit will be released immediately.
poolConfig.setMaxIdle(10);
// Set minimum idle connections; new idle connections will be created if below this threshold.
poolConfig.setMinIdle(3);
// Maximum wait time when no available connections exist and max connection count is reached.
poolConfig.setMaxWait(Duration.ofSeconds(1));
// PING to verify connection availability each time a connection is borrowed from the pool.
poolConfig.setTestOnBorrow(true);
// Test idle connections to detect and release invalid ones; only effective when timeBetweenEvictionRunsMillis > 1ms.
poolConfig.setTestWhileIdle(true);
// Set minimum idle duration for connections; connections exceeding this time will be released. -1 means never release. Only effective when timeBetweenEvictionRunsMillis > 0. Default: 30m.
poolConfig.setMinEvictableIdleDuration(Duration.ofMinutes(5));
// Number of connections to validate during each idle connection check; -n means 1/n of connections.
poolConfig.setNumTestsPerEvictionRun(-1);
// Set idle connection check interval; negative value means no eviction thread runs.
poolConfig.setTimeBetweenEvictionRuns(Duration.ofMinutes(1));
// Maximum retry attempts.
int maxAttempts = 3;
// Maximum retry duration.
Duration maxAttemptsDuration = Duration.ofSeconds(3);
// Topology refresh interval.
Duration topologyRefreshPeriod = Duration.ofMinutes(1);
JedisClientConfig clientConfig = DefaultJedisClientConfig.builder()
// Connection timeout, default 2 seconds.
.connectionTimeoutMillis(2000)
// Command timeout.
.timeoutMillis(10000)
// Client name for identifying connection source during debugging.
.clientName("demo-jedis")
.password("<password>")
.build();
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("<ip1>", <port1>));
nodes.add(new HostAndPort("<ip2>", <port2>));
JedisCluster cluster = new JedisCluster(nodes, clientConfig, poolConfig, topologyRefreshPeriod, maxAttempts, maxAttemptsDuration);
try {
String val = cluster.get("test");
System.out.printf("%s", val);
} catch (Exception e) {
e.printStackTrace();
}
cluster.close();
}
}有关更详细的配置,请参阅 Community Documentation
package io.alauda.demo.redis;
// It is recommended to periodically upgrade to the latest version of the client for the latest bug fixes.
import io.lettuce.core.ClientOptions;
import io.lettuce.core.RedisURI;
import io.lettuce.core.SocketOptions;
import io.lettuce.core.TimeoutOptions;
import io.lettuce.core.cluster.ClusterClientOptions;
import io.lettuce.core.cluster.ClusterTopologyRefreshOptions;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
import io.lettuce.core.support.ConnectionPoolSupport;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import java.time.Duration;
import java.util.List;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
RedisURI node1 = RedisURI.create("<ip1>", <port1>);
node1.setPassword("<password>");
node1.setClientName("demo-lettuce");
RedisURI node2 = RedisURI.create("<ip2>", <port2>);
node2.setPassword("<password>");
node2.setClientName("demo-lettuce");
List<RedisURI> nodes = new ArrayList<>();
nodes.add(node1);
nodes.add(node2);
ClusterTopologyRefreshOptions refreshOptions = ClusterTopologyRefreshOptions.builder()
// The default interval for refreshing topology is 60 seconds.
.enablePeriodicRefresh()
// Triggers topology refresh when encountering the following errors: ASK_REDIRECT, MOVED_REDIRECT, PERSISTENT_RECONNECTS, UNCOVERED_SLOT, UNKNOWN_NODE
.enableAllAdaptiveRefreshTriggers()
.build();
TimeoutOptions timeoutOptions = TimeoutOptions.builder()
// Sets the command timeout.
.fixedTimeout(Duration.ofSeconds(10))
.build();
SocketOptions socketOptions = SocketOptions.builder()
// Sets the connection timeout.
.connectTimeout(Duration.ofSeconds(10))
.tcpNoDelay(true)
// Enables TCP keepalive to quickly identify invalid connections.
// This value is not mandatory for non-pub/sub requests; it can be managed via timely release of idle connections.
.keepAlive(true)
.build();
ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder()
.topologyRefreshOptions(refreshOptions)
// Sets the command timeout.
.timeoutOptions(timeoutOptions)
// Automatic reconnection (default behavior).
.autoReconnect(true)
// Configures client behavior when disconnected.
// DEFAULT - When autoReconnect = true, commands will not be rejected when they come in; otherwise, commands will be rejected.
.disconnectedBehavior(ClientOptions.DisconnectedBehavior.DEFAULT)
// Configures socket parameters; lettuce does not enable keepalive by default; this should be enabled for long connection business needs.
.socketOptions(socketOptions)
.build();
RedisClusterClient redisClient = RedisClusterClient.create(nodes);
redisClient.setOptions(clusterClientOptions);
GenericObjectPoolConfig<StatefulRedisClusterConnection<String, String>> poolConfig = new GenericObjectPoolConfig<>();
// Connection pool size should not be too large to avoid wasting server connection resources, leading to exhaustion of connections and instance unavailability.
// It is recommended to estimate your business concurrency divided by the number of shards; the final value should be 1.2-1.5 times.
poolConfig.setMaxTotal(200);
// Minimum number of idle connections to reserve for faster business response.
poolConfig.setMinIdle(3);
// Maximum number of idle connections; exceeding this limit will release idle connections immediately.
poolConfig.setMaxIdle(10);
// Minimum idle duration for connections.
poolConfig.setMinEvictableIdleDuration(Duration.ofMinutes(5));
// Number of connections to validate during each idle connection check; -n means 1/n of connections.
poolConfig.setNumTestsPerEvictionRun(3);
// Eviction interval; -1 means disable.
poolConfig.setTimeBetweenEvictionRuns(Duration.ofMinutes(1));
// Maximum wait time when no available connections and max connection count is reached.
poolConfig.setMaxWait(Duration.ofSeconds(1));
// PING to verify if the connection is available each time a connection is borrowed.
poolConfig.setTestOnBorrow(true);
// Test idle connections to find invalid ones and release them; this configuration only takes effect when timeBetweenEvictionRunsMillis is greater than 1ms.
poolConfig.setTestWhileIdle(true);
GenericObjectPool<StatefulRedisClusterConnection<String, String>> pool = ConnectionPoolSupport
.createGenericObjectPool(redisClient::connect, poolConfig);
try {
try (StatefulRedisClusterConnection<String, String> connection = pool.borrowObject()) {
String val = connection.sync().get("test");
System.out.printf("%s", val);
}
} catch (Exception e) {
e.printStackTrace();
}
pool.close();
}
}有关更详细的配置,请参阅 Community Documentation
package io.alauda.demo.redis;
// It is recommended to periodically upgrade to the latest version of the client for the latest bug fixes.
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.List;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
List<String> nodes = new ArrayList<>();
nodes.add("redis://<ip1>:<port1>");
nodes.add("redis://<ip2>:<port2>");
Config config = new Config();
config
.setNettyThreads(64)
.useClusterServers()
.addNodeAddress(nodes.toArray(new String[0]))
.setPassword("<password>")
// Check cluster slots state on service startup.
.setCheckSlotsCoverage(true)
// Interval for scanning cluster topology.
.setScanInterval(5000)
// Connection timeout.
.setConnectTimeout(10000)
// Command timeout.
.setTimeout(10000)
// Every 30 seconds test a connection for availability.
// If KeepAlive is enabled, this timeout can be proportionally extended.
.setPingConnectionInterval(30000)
// Idle connection timeout; drop connections idle for more than 60 seconds, default of 10 seconds is too short.
.setIdleConnectionTimeout(60000)
// Connection pool size should not be too large to avoid wasting server connection resources, leading to exhaustion of connections and instance unavailability.
// It is recommended to estimate your business concurrency divided by the number of shards; the final value should be 1.2-1.5 times.
.setMasterConnectionPoolSize(200)
// Minimum number of idle connections to reserve for faster business response.
.setMasterConnectionMinimumIdleSize(10)
// Number of retry attempts for failed commands.
.setRetryAttempts(3)
// Retry interval for failed commands.
.setRetryInterval(1500)
// Enable TCP keepalive mechanism for quick discovery of unexpectedly disconnected connections.
.setKeepAlive(true)
// TCP no delay.
.setTcpNoDelay(true)
// Client name for checking connection source during debugging.
.setClientName("demo-redisson");
RedissonClient redissonClient = Redisson.create(config);
System.out.printf("%s", redissonClient.getBucket("test").get().toString());
redissonClient.shutdown();
}
}有关更详细的配置,请参阅 Community Documentation