All Products
Search
Document Center

Tair (Redis® OSS-Compatible):Connect to a Tair Serverless KV Redis-compatible instance

Last Updated:Aug 25, 2026

This topic shows how to connect to a Tair Serverless KV Redis-compatible instance using redis-cli and code examples.

Prerequisites

Connect to the instance

The following table lists the parameters required to connect.

Parameter

Description

How to obtain

hostname

endpoint

  1. Go to the Instances page, select a region in the top navigation bar, and then click the ID of the target instance.

  2. On the Instance Information page, the Connection Information section contains the endpoint and port number.

port

port number

The default port number is 6379. You can also customize the port number. For more information, see Modify an endpoint or port number.

password

password

Enter the username and password based on the account type:

  • For a default account (usually named default or named after the instance ID): Enter only the password.

  • For a standard account: Use the user:password format. For example, if the custom username is testaccount and the password is Rp829dlwa, you must enter testaccount:Rp829dlwa.

If you forget your password or have not set one, you can change or reset the password.

Note

Tair Serverless KV uses a distributed architecture and is compatible with the native Redis Cluster protocol. Ensure that your client connects to the instance in Redis Cluster mode.

Connect using code

Jedis

In this example, Jedis 4.3.0 is used. For more information, visit GitHub.

  • Custom connection pool (recommended)

    import redis.clients.jedis.*;
    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 ConnectionPoolConfig config = new ConnectionPoolConfig();
    
        public static void main(String args[]) {
            // Specify the maximum number of connections. In direct connection mode, the client directly connects to a shard of a cluster instance. Therefore, the following requirement must be met: Number of clients × Value of MaxTotal < Maximum number of connections to a single shard. 
            config.setMaxTotal(30);
            // Specify the maximum number of idle connections based on your business needs. 
            config.setMaxIdle(20);
            config.setMinIdle(15);
    
            // Specify the private endpoint that is allocated to the cluster instance. 
            String host = "r-bp1xxxxxxxxxxxx.redis.rds.aliyuncs.com";
            int port = 6379;
            // Specify the password that is used to connect to the cluster instance. 
            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);
    
            jc.set("key", "value");
            jc.get("key");
    
            jc.close();     // If the application exits and you want to destroy the resources, call this method. This way, the connection is closed, and the resources are released. 
        }
    }
  • Default connection pool

    import redis.clients.jedis.ConnectionPoolConfig;
    import redis.clients.jedis.HostAndPort;
    import redis.clients.jedis.JedisCluster;
    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 ConnectionPoolConfig DEFAULT_CONFIG = new ConnectionPoolConfig();
    
        public static void main(String args[]){
    
            // Specify the private endpoint that is allocated to the cluster instance. 
            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();     // If the application exits and you want to destroy the resources, call this method. This way, the connection is closed, and the resources are released. 
        }
    }

Connect with Spring Data Redis

The following Maven project uses Spring Data Redis 2.4.2. Alternatively, download the Lettuce or Jedis client manually.

Step 1: Add Maven dependencies

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.aliyun.tair</groupId>
    <artifactId>spring-boot-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-example</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
            <version>6.3.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-transport-native-epoll</artifactId>
            <version>4.1.100.Final</version>
            <classifier>linux-x86_64</classifier>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Step 2: Configure the connection

Choose either Jedis (recommended) or Lettuce as the underlying client.

Spring Data Redis with Jedis (recommended)
@Bean
    JedisConnectionFactory redisConnectionFactory() {
        List<String> clusterNodes = Arrays.asList("r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379");
        RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(clusterNodes);
        redisClusterConfiguration.setUsername("user");
        redisClusterConfiguration.setPassword("password");


        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // Number of clients x MaxTotal < Maximum connections to a single shard.
        jedisPoolConfig.setMaxTotal(30);
        jedisPoolConfig.setMaxIdle(20);
        // Disable testOn[Borrow|Return] to avoid extra ping commands.
        jedisPoolConfig.setTestOnBorrow(false);
        jedisPoolConfig.setTestOnReturn(false);

        return new JedisConnectionFactory(redisClusterConfiguration, jedisPoolConfig);
    }
Spring Data Redis with Lettuce
Warning
/**
     * Enable TCP keepalive and configure the following three parameters:
     *  TCP_KEEPIDLE = 30
     *  TCP_KEEPINTVL = 10
     *  TCP_KEEPCNT = 3
     */
    private static final int TCP_KEEPALIVE_IDLE = 30;

    /**
     * TCP_USER_TIMEOUT avoids scenarios where Lettuce remains stuck in a
     * continuous timeout loop during a failure or crash event.
     * refer: https://github.com/lettuce-io/lettuce-core/issues/2082
     */
    private static final int TCP_USER_TIMEOUT = 30;

    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        List<String> clusterNodes = Arrays.asList("r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379");
        RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(clusterNodes);
        redisClusterConfiguration.setUsername("user");
        redisClusterConfiguration.setPassword("password");

        // Config TCP KeepAlive
        SocketOptions socketOptions = SocketOptions.builder()
            .keepAlive(KeepAliveOptions.builder()
                .enable()
                .idle(Duration.ofSeconds(TCP_KEEPALIVE_IDLE))
                .interval(Duration.ofSeconds(TCP_KEEPALIVE_IDLE / 3))
                .count(3)
                .build())
            .tcpUserTimeout(TcpUserTimeoutOptions.builder()
                .enable()
                .tcpUserTimeout(Duration.ofSeconds(TCP_USER_TIMEOUT))
                .build())
            .build();

        ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder()
            .enablePeriodicRefresh(Duration.ofSeconds(60))
            .dynamicRefreshSources(false)
            .enableAllAdaptiveRefreshTriggers()
            .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(15)).build();

        LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder().
            clientOptions(ClusterClientOptions.builder()
                .socketOptions(socketOptions)
                .validateClusterNodeMembership(false)
                .topologyRefreshOptions(topologyRefreshOptions).build()).build();

        return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration);
    }

PhpRedis

In this example, PhpRedis 5.3.7 is used. For more information, visit GitHub.

<?php
 // Specify the private endpoint and port number that are used to connect to the cluster instance. 
 $array = ['r-bp1xxxxxxxxxxxx.redis.rds.aliyuncs.com:6379'];
 // Specify the password that is used to connect to the cluster instance. 
 $pwd = "xxxx";
 
 // Use the password to connect to the cluster instance. 
 $obj_cluster = new RedisCluster(NULL, $array, 1.5, 1.5, true, $pwd);
 
 // Display the result of the connection. 
 var_dump($obj_cluster);
 
 if ($obj_cluster->set("foo", "bar") == false) {
     die($obj_cluster->getLastError());
 }
 $value = $obj_cluster->get("foo");
 echo $value;
 ?>

redis-py

In this example, Python 3.9 and redis-py 4.4.1 are used. For more information, visit GitHub.

# !/usr/bin/env python
# -*- coding: utf-8 -*-
from redis.cluster import RedisCluster
# Replace the values of the host and port parameters with the endpoint and port number that are used to connect to the instance. 
host = 'r-bp10noxlhcoim2****.redis.rds.aliyuncs.com'
port = 6379
# Replace the values of the user and pwd parameters with the username and password that are used to connect to the instance. 
user = 'testaccount'
pwd = 'Rp829dlwa'
rc = RedisCluster(host=host, port=port, username=user, password=pwd)
# You can perform operations on the instance after the connection is established. The following code provides an example on how to call the set and get methods: 
rc.set('foo', 'bar')
print(rc.get('foo'))

.NET

In this example, .NET 6.0 and StackExchange.Redis 2.6.90 are used.

using StackExchange.Redis;

class RedisConnSingleton {
    // Specify the endpoint, port number, username, and password that are used to connect to the cluster instance. 
    private static ConfigurationOptions configurationOptions = ConfigurationOptions.Parse("r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379,user=testaccount,password=Rp829dlwa,connectTimeout=2000");
    //the lock for singleton
    private static readonly object Locker = new object();
    //singleton
    private static ConnectionMultiplexer redisConn;
    //singleton
    public static ConnectionMultiplexer getRedisConn()
    {
        if (redisConn == null)
        {
            lock (Locker)
            {
                if (redisConn == null || !redisConn.IsConnected)
                {
                    redisConn = ConnectionMultiplexer.Connect(configurationOptions);
                }
            }
        }
        return redisConn;
    }
}

class Program
{
    static void Main(string[] args)
    {
        ConnectionMultiplexer cm = RedisConnSingleton.getRedisConn();
        var db = cm.GetDatabase();
        db.StringSet("key", "value");
        String ret = db.StringGet("key");
        Console.WriteLine("get key: " + ret);
    }
}

node-redis

In this example, Node.js 19.4.0 and node-redis 4.5.1 are used.

import { createCluster } from 'redis';

// Specify the endpoint, port number, username, and password that are used to connect to the instance. 
// After you supply the username and password for the url parameter, you must also supply the global username and password for the defaults parameter. 
// The global username and password are used to authenticate the remaining nodes. If the remaining nodes are not authenticated, the NOAUTH error occurs. 

const cluster = createCluster({
    rootNodes: [{
        url: 'redis://testaccount:Rp829dlwa@r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379'
    }],
    defaults: {
        username: 'testaccount',
        password: 'Rp829dlwa'
    }
});

cluster.on('error', (err) => console.log('Redis Cluster Error', err));

await cluster.connect();

await cluster.set('key', 'value');
const value = await cluster.get('key');
console.log('get key: %s', value);

await cluster.disconnect();

Go-redis

In this example, Go 1.19.7 and go-redis 9.5.1 are used.

Important

Use go-redis 9.0 or later. If you use a go-redis version earlier than 9.0, an incompatibility error may occur when you connect to a private endpoint. For more information, see Common errors and troubleshooting.

package main

import (
	"context"
	"fmt"
	"github.com/go-redis/redis/v9"
)

var ctx = context.Background()

func main() {
	rdb := redis.NewClusterClient(&redis.ClusterOptions{
		Addrs:    []string{"r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379"},
		Username: "testaccount",
		Password: "Rp829dlwa",
	})

	err := rdb.Set(ctx, "key", "value", 0).Err()
	if err != nil {
		panic(err)
	}

	val, err := rdb.Get(ctx, "key").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println("key", val)
}

Connect with Lettuce (standalone)

Warning

Step 1: Add Maven dependencies

<dependency>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
            <version>6.3.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-transport-native-epoll</artifactId>
            <version>4.1.65.Final</version>
            <classifier>linux-x86_64</classifier>
        </dependency>

Step 2: Add the connection code

Replace the values of host, port, and password with the actual instance information.

import io.lettuce.core.RedisURI;
import io.lettuce.core.SocketOptions;
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 java.time.Duration;

public class ClusterDemo {
    /**
     * Enable TCP keepalive and configure the following three parameters:
     *  TCP_KEEPIDLE = 30
     *  TCP_KEEPINTVL = 10
     *  TCP_KEEPCNT = 3
     */
    private static final int TCP_KEEPALIVE_IDLE = 30;

    /**
     * TCP_USER_TIMEOUT avoids situations where Lettuce remains stuck in a
     * continuous timeout loop during a failure or crash event.
     * refer: https://github.com/lettuce-io/lettuce-core/issues/2082
     */
    private static final int TCP_USER_TIMEOUT = 30;

    public static void main(String[] args) throws Exception {
        // Replace with the actual instance information.
        String host = "r-bp1ln3c4kopj3l****.redis.rds.aliyuncs.com";
        int port = 6379;
        String password = "Da****3";

        RedisURI redisURI = RedisURI.Builder.redis(host)
                .withPort(port)
                .withPassword(password)
                .build();

        ClusterTopologyRefreshOptions refreshOptions = ClusterTopologyRefreshOptions.builder()
                .enablePeriodicRefresh(Duration.ofSeconds(60))
                .dynamicRefreshSources(false)
                .enableAllAdaptiveRefreshTriggers()
                .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(15)).build();

        // Config TCP KeepAlive
        SocketOptions socketOptions = SocketOptions.builder()
                .keepAlive(SocketOptions.KeepAliveOptions.builder()
                        .enable()
                        .idle(Duration.ofSeconds(TCP_KEEPALIVE_IDLE))
                        .interval(Duration.ofSeconds(TCP_KEEPALIVE_IDLE/3))
                        .count(3)
                        .build())
                .tcpUserTimeout(SocketOptions.TcpUserTimeoutOptions.builder()
                        .enable()
                        .tcpUserTimeout(Duration.ofSeconds(TCP_USER_TIMEOUT))
                        .build())
                .build();

        RedisClusterClient redisClient = RedisClusterClient.create(redisURI);
        redisClient.setOptions(ClusterClientOptions.builder()
                .socketOptions(socketOptions)
                .validateClusterNodeMembership(false)
                .topologyRefreshOptions(refreshOptions).build());

        StatefulRedisClusterConnection<String, String> connection = redisClient.connect();
        connection.sync().set("key", "value");
        System.out.println(connection.sync().get("key"));
    }
}

Expected output on success:

value

Connect using redis-cli

  1. Connect to the instance:

    ./redis-cli -h r-bp1zxszhcgatnx****.redis.rds.aliyuncs.com -p 6379 -c
  2. Authenticate the connection.

    AUTH testaccount:Rp829dlwa

For more information about redis-cli, see Connect to an instance using redis-cli.

FAQ

  • Q: What do I do if my ECS instance and Tair Serverless KV Redis-compatible instance are not in the same VPC?

    A: You can either change the VPC of the ECS instance to match the Tair Serverless KV instance's VPC, or create a new Tair Serverless KV instance in the same VPC as the ECS instance.

  • Q: Can the client and the Tair Serverless KV instance be in different availability zones?

    A: Yes. As long as they are in the same VPC, they can connect. Cross-availability zone connections typically add only 1–2 ms of latency.