All Products
Search
Document Center

Tair (Redis® OSS-Compatible):Mitigate hot spot key issues with read/write splitting

Last Updated:Mar 28, 2026

When a small set of keys receives a disproportionate share of read traffic, the primary node becomes a bottleneck. Enabling read/write splitting and adding read-only nodes distributes those reads across all nodes — reducing load on the primary node and scaling read throughput linearly with each node added.

Use cases

Read/write splitting suits workloads that can tolerate slightly outdated data during periods of high write volume, because read-only nodes replicate from the primary node asynchronously with low but non-zero lag. Typical scenarios include:

  • Cached page content: HTML caches for website home pages that are refreshed infrequently.

  • Game leaderboards: Hourly rankings where a minor update delay has no meaningful impact.

  • Weather forecast data: Frequently queried data that updates on a fixed schedule.

How it works

All read-only nodes replicate data from the primary node asynchronously, providing eventual consistency. The primary node handles 100% of write requests and 1/N of read requests, where N is the total number of nodes (primary + read-only). For example, with one primary node and three read-only nodes, N is 4, and read performance scales up to 4x. This reduces the CPU pressure, network traffic, and connection overhead on the primary node.

A built-in Proxy component routes requests automatically: write requests go to the primary node, and read requests are distributed across read-only nodes. No client code changes are required for single-zone instances.

Read/write splitting is supported for both standard (primary-replica) and cluster architectures. In a cluster architecture, each data shard can have its own read-only node. For architecture details, see Read/write splitting.

Prerequisites

Before you begin, ensure that you have:

  • An instance deployed in cloud-native mode

  • An instance type that is Redis Open-Source Edition, Tair (Enterprise Edition) DRAM-optimized, or Tair (Enterprise Edition) persistent memory-optimized

  • An instance with at least 1 GB of memory

  • A high availability instance

Enable read/write splitting

On the instance details page, click Node Management in the left navigation pane, then turn on the Read/write Splitting switch. For step-by-step instructions, see Enable read/write splitting.

Connect your client

Single-zone instances

Single-zone instances expose a single endpoint. The built-in Proxy routes read and write requests to the appropriate nodes automatically — connect using your existing endpoint and password without modifying your code.

For connection examples, see the client connection tutorial.

Dual-zone instances

Dual-zone instances expose two endpoints: one for the primary zone (read and write) and one for the secondary zone (read only). Clients in the secondary zone connect to the secondary zone endpoint for reads, reducing cross-zone latency. Write operations always go to the primary zone endpoint.

The following examples use Hangzhou Zone I (primary zone) and Hangzhou Zone J (secondary zone).

Primary zone client — read and write

A client in Hangzhou Zone I connects to the primary zone endpoint to perform both reads and writes:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class MasterReadWrite {
    public static void main(String[] args) {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(200);
        config.setMaxTotal(300);
        config.setTestOnBorrow(false);
        config.setTestOnReturn(false);

        // Primary zone endpoint, port, and password
        String host = "r-bp1vtq8tnrquy****pd.redis.rds.aliyuncs.com";
        int port = 6379;
        String password = "default:Passw***2";

        JedisPool pool = new JedisPool(config, host, port, 3000, password);
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            jedis.set("foo", "bar");
            System.out.println(jedis.get("foo"));
        }
        catch (Exception e) {
            // Handle timeouts or other exceptions.
            e.printStackTrace();
        }
        finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        pool.destroy();    // On application exit, call this method to release connections and resources.
    }
}

Secondary zone client — read only

A client in Hangzhou Zone J connects to the secondary zone endpoint for reads. The secondary zone endpoint is for read operations only — catch JedisDataException to handle any accidental write attempts gracefully:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class ReplicaRead {
    public static void main(String[] args) {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxIdle(200);
        config.setMaxTotal(300);
        config.setTestOnBorrow(false);
        config.setTestOnReturn(false);

        // Secondary zone endpoint, port, and password
        String host = "r-bp1vtq8tnrquy****pd.redis.rds.aliyuncs.com";
        int port = 6379;
        String password = "default:Passw***2";

        JedisPool pool = new JedisPool(config, host, port, 3000, password);
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            System.out.println(jedis.get("foo"));
        }
        catch (JedisDataException e) {
            // The secondary zone endpoint is read-only. Catch this exception if a write command is sent by mistake.
            e.getMessage();
        }
        catch (Exception e) {
            // Handle timeouts or other exceptions.
            e.printStackTrace();
        }
        finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        pool.destroy();    // On application exit, call this method to release connections and resources.
    }
}

Related topics