// Create RedisURI from the MRC discovery endpoint
RedisURI redisUri = RedisURI.Builder.redis(CLUSTER_DISC_EP_ADDR, CLUSTER_DISC_EP_PORT).build();
// Configure client' resources
// Configure reconnectDelay with exponential backoff and full jitter
ClientResources resources = DefaultClientResources.builder()
.reconnectDelay(Delay.fullJitter(
Duration.ofMillis(100), // minimum 100 millisecond delay
Duration.ofSeconds(5), // maximum 5 second delay
100, TimeUnit.MILLISECONDS) // 100 millisecond base
).build();
// Create a cluster client with the URI and resources
RedisClusterClient clusterClient = RedisClusterClient.create(resources, redisUri);
// Configure the topology refreshment options
// Enable periodic cluster topology updates so that the client updates the cluster topology in the intervals of
// 60 seconds
// Enable adaptive topology refresh that uses all triggers: MOVED_REDIRECT, ASK_REDIRECT,
// PERSISTENT_RECONNECTS, UNCOVERED_SLOT, UNKNOWN_NODE
// Disable dynamicRefreshSources so that only the initial seed nodes (Memorystore for Redis Cluster
// discovery endpoint) will be used as the source for topology discovery
// Enable closing stale connections when refreshing the cluster topology. This reduces the need to handle
// failed connections during command runtime.
ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
.enablePeriodicRefresh(1, TimeUnit.MINUTES)
.enableAllAdaptiveRefreshTriggers()
.dynamicRefreshSources(false)
.closeStaleConnections(true)
.build();
// Configure the socket options
// Set connectTimeout based on your application requirements and workload
// Enable TCP keepAlive to reduce the need to handle failed connections during command runtime
SocketOptions socketOptions = SocketOptions.builder()
.connectTimeout(CONNECT_TIMEOUT)
.keepAlive(true)
.build();
// Configure the client options
// Enable AutoReconnect when connection is lost
// Set nodeFilter to filter out failed nodes from the topology
// Disable validateClusterNodeMembership to allow redirecting commands to newly added nodes
clusterClient.setOptions(ClusterClientOptions.builder()
.topologyRefreshOptions(topologyRefreshOptions)
.socketOptions(socketOptions)
.autoReconnect(true)
.nodeFilter(it ->
! (it.is(RedisClusterNode.NodeFlag.FAIL)
|| it.is(RedisClusterNode.NodeFlag.EVENTUAL_FAIL)
|| it.is(RedisClusterNode.NodeFlag.NOADDR)))
.validateClusterNodeMembership(false)
.build());
// Create a connection pool
GenericObjectPool<StatefulRedisClusterConnection<String, String> pool = ConnectionPoolSupport.createGenericObjectPool(() -> clusterClient.connect(), new GenericObjectPoolConfig());
pool.setMaxTotal(MAX_CONNECTIONS_IN_CONNECTION_POOL);
// Get a connection from the connection pool
StatefulRedisClusterConnection<String, String> connection = pool.borrowObject();
// Get a cluster sync command and call 'set'
RedisAdvancedClusterCommands<String, String> syncCommands = connection.sync();
syncCommands.set(key, value);
// Create a cluster client. A connection pool is used internally.
cluster_client = redis.RedisCluster(
host=CLUSTER_DISC_EP_ADDR,
port=CLUSTER_DISC_EP_PORT,
retry=Retry(EqualJitterBackoff(), 3))
cluster_client.set('key', 'value')
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["難以理解","hardToUnderstand","thumb-down"],["資訊或程式碼範例有誤","incorrectInformationOrSampleCode","thumb-down"],["缺少我需要的資訊/範例","missingTheInformationSamplesINeed","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-09-04 (世界標準時間)。"],[],[],null,["# Client library code samples\n\nThis page provides examples of Memorystore for Redis Cluster configurations for\ndifferent client libraries.\n\nLettuce\n-------\n\nWe recommend using [Lettuce](https://lettuce.io/), versions 6.2.4 and later.\n**Caution** : If you use Lettuce to connect to a Memorystore for Redis Cluster instance, then change the `validateClusterNodeMembership` parameter to `false`. Otherwise, when the topology changes, you might get `unknownPartition` errors. \n\n### Lettuce\n\n```\n\n// Create RedisURI from the MRC discovery endpoint\nRedisURI redisUri = RedisURI.Builder.redis(CLUSTER_DISC_EP_ADDR, CLUSTER_DISC_EP_PORT).build();\n\n// Configure client' resources\n// Configure reconnectDelay with exponential backoff and full jitter\nClientResources resources = DefaultClientResources.builder()\n .reconnectDelay(Delay.fullJitter(\n Duration.ofMillis(100), // minimum 100 millisecond delay\n Duration.ofSeconds(5), // maximum 5 second delay\n 100, TimeUnit.MILLISECONDS) // 100 millisecond base\n).build();\n\n// Create a cluster client with the URI and resources\nRedisClusterClient clusterClient = RedisClusterClient.create(resources, redisUri);\n\n// Configure the topology refreshment options\n// Enable periodic cluster topology updates so that the client updates the cluster topology in the intervals of\n// 60 seconds\n// Enable adaptive topology refresh that uses all triggers: MOVED_REDIRECT, ASK_REDIRECT,\n// PERSISTENT_RECONNECTS, UNCOVERED_SLOT, UNKNOWN_NODE\n// Disable dynamicRefreshSources so that only the initial seed nodes (Memorystore for Redis Cluster\n// discovery endpoint) will be used as the source for topology discovery\n// Enable closing stale connections when refreshing the cluster topology. This reduces the need to handle\n// failed connections during command runtime.\nClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()\n .enablePeriodicRefresh(1, TimeUnit.MINUTES)\n .enableAllAdaptiveRefreshTriggers()\n .dynamicRefreshSources(false)\n .closeStaleConnections(true)\n .build();\n\n// Configure the socket options\n// Set connectTimeout based on your application requirements and workload\n// Enable TCP keepAlive to reduce the need to handle failed connections during command runtime\nSocketOptions socketOptions = SocketOptions.builder()\n .connectTimeout(CONNECT_TIMEOUT)\n .keepAlive(true)\n .build();\n\n// Configure the client options\n// Enable AutoReconnect when connection is lost\n// Set nodeFilter to filter out failed nodes from the topology\n// Disable validateClusterNodeMembership to allow redirecting commands to newly added nodes\n\nclusterClient.setOptions(ClusterClientOptions.builder()\n .topologyRefreshOptions(topologyRefreshOptions)\n .socketOptions(socketOptions)\n .autoReconnect(true)\n .nodeFilter(it -\u003e\n ! (it.is(RedisClusterNode.NodeFlag.FAIL)\n || it.is(RedisClusterNode.NodeFlag.EVENTUAL_FAIL)\n || it.is(RedisClusterNode.NodeFlag.NOADDR)))\n .validateClusterNodeMembership(false)\n .build());\n\n// Create a connection pool\nGenericObjectPool\u003cStatefulRedisClusterConnection\u003cString, String\u003e pool = ConnectionPoolSupport.createGenericObjectPool(() -\u003e clusterClient.connect(), new GenericObjectPoolConfig());\npool.setMaxTotal(MAX_CONNECTIONS_IN_CONNECTION_POOL);\n\n// Get a connection from the connection pool\nStatefulRedisClusterConnection\u003cString, String\u003e connection = pool.borrowObject();\n\n// Get a cluster sync command and call 'set'\nRedisAdvancedClusterCommands\u003cString, String\u003e syncCommands = connection.sync();\nsyncCommands.set(key, value);\n\n```\n\nredis-py\n--------\n\nWe recommend using [redis-py](https://github.com/redis/redis-py), versions 5.1\nand later. \n\n### redis-py\n\n```\n\n// Create a cluster client. A connection pool is used internally.\ncluster_client = redis.RedisCluster(\n host=CLUSTER_DISC_EP_ADDR,\n port=CLUSTER_DISC_EP_PORT,\n retry=Retry(EqualJitterBackoff(), 3))\n\ncluster_client.set('key', 'value')\n\n```\n\nPHPRedis\n--------\n\nWe recommend using [PHPRedis](https://github.com/phpredis/phpredis), versions\n5.0.0 and later. \n\n### PHPRedis\n\n```\n\n// In redis.ini\nredis.clusters.seeds = \"cluster[]=CLUSTER_DISC_EP_ADDR:CLUSTER_DISC_EP_PORT\"\nredis.clusters.cache_slots = \"cluster=1\"\nredis.clusters.persistent = \"cluster=1\"\n\n$cluster = new RedisCluster('cluster');\n$cluster-\u003eset(\"key\", \"value\");\n\n```\n\nRedisson\n--------\n\nWe recommend using [Redisson](https://redisson.org/), versions 3.20.1 and later. \n\n### Redisson\n\n```\n\nConfig config = new Config();\nClusterServersConfig clusterConfig = config.useClusterServers()\n .addNodeAddress(\"redis://CLUSTER_DISC_EP_ADDR:CLUSTER_DISC_EP_PORT\")\n .setScanInterval(60000) // cluster topology periodic refresh\n .setMasterConnectionMinimumIdleSize(1)\n .setMasterConnectionPoolSize(10)\n .setSlaveConnectionMinimumIdleSize(1)\n .setSlaveConnectionPoolSize(10)\n .setIdleConnectionTimeout(60000)\n .setPingConnectionInterval(0)\n .setKeepAlive(true)\n .setTcpNoDelay(true)\n\nRedissonClient redisson = Redisson.create(config);\nRBucket\u003cString\u003e bucket = redisson.getBucket(\"key\");\nbucket.set(\"value\");\n\n```\n\ngo-redis\n--------\n\nWe recommend using [go-redis](https://github.com/redis/go-redis), versions\n9.11.0 and later. \n\n### go-redis\n\n```\n\nclusterClient = redis.NewClusterClient(&redis.ClusterOptions{\n Addrs: []string{\"CLUSTER_DISC_EP_ADDR:CLUSTER_DISC_EP_PORT\"},\n // PoolSize applies per cluster node and not for the whole cluster.\n PoolSize: 10,\n ConnMaxIdleTime: 60 * time.Second,\n MinIdleConns: 1,\n})\n\nctx := context.Background()\n\nerr := clusterClient.Set(ctx, \"key\", \"value\", 0).Err()\n\n```"]]