全部產品
Search
文件中心

Tair (Redis® OSS-Compatible):通過讀寫分離緩解熱點Key問題

更新時間:Sep 13, 2025

為緩解熱點Key帶來大量讀請求的影響,您可以啟用讀寫分離功能並增加唯讀節點,系統能夠將讀請求分散至各個節點。這將降低主節點的壓力,並提升系統的整體輸送量和穩定性。

功能概述

讀寫分離架構的所有隻讀節點通過非同步複製主節點的資料(最終一致性),整體資料同步延遲低。這意味著在部分寫入量較大的情況下,可能會發生資料同步延遲,此時應用程式能夠容忍稍舊的資料。例如下述情境:

  • 快取資料:網址首頁的HTML緩衝等,更新頻率低。

  • 遊戲熱門排行榜:小時層級熱門排行榜,其輕微的更新延遲對使用者影響並不顯著。

  • 天氣預報資料:使用者頻繁查詢天氣,資料則按照預定時間進行更新。

增加唯讀節點的直接作用

  • 分擔主節點負載:主節點僅負責100%寫請求、1/N的讀請求(N為總節點數,例如1個主節點、3個唯讀節點,即N為4)。這降低了主節點的CPU壓力、網路壓力,以及串連開銷。

  • 提高系統輸送量:每個唯讀節點可獨立處理讀請求,整體讀效能呈線性擴充。在理想情況下,增加N個唯讀節點可提升N倍讀效能。

  • 降低響應延遲:將讀請求分散到多個節點後,可減少單個請求的排隊等待時間。

不僅支援為標準(主從)架構開啟讀寫分離,也支援為叢集架構開啟讀寫分離,可為叢集的每個資料分區節點增加對應的唯讀節點,具體架構資訊請參見讀寫分離功能

如何開啟

前提條件:

  • 部署模式為雲原生

  • 執行個體為Redis開源版Tair(企業版)記憶體型、持久記憶體型。

  • 執行個體規格為1 GB及以上。

  • 執行個體類型為高可用。

開啟方法:在執行個體詳情頁中,單擊左側導覽列的節點管理,並開啟讀寫分離開關。具體操作請參見開啟讀寫分離

用戶端串連

單可用性區域執行個體

通常情況下,讀寫分離架構執行個體仍提供一個串連地址,執行個體將通過Proxy組件實現路由分發。您無需修改代碼,開箱即用,更多資訊請參見用戶端程式串連教程

雙可用性區域執行個體

在雙可用性區域、讀寫分離架構執行個體,執行個體將分別提供主、備可用性區域串連地址。其中備可用性區域串連地址僅用於讀請求,可實現就近訪問,縮短讀請求延遲。

例如執行個體為杭州I(主可用性區域)、杭州J(備可用性區域)。

  • 位於杭州I的用戶端(ECS執行個體)可以串連執行個體的主可用性區域地址,並執行讀寫操作。代碼如下:

    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);
    
            // 配置主可用性區域串連地址、連接埠、帳號密碼資訊。
            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) {
                // 逾時或其他異常處理。
                e.printStackTrace();
            }
            finally {
                if (jedis != null) {
                    jedis.close();
                }
            }
            pool.destroy();    // 當應用退出,需銷毀資源時,調用此方法。此方法會中斷連線、釋放資源。
        }
    }
  • 位於杭州J的用戶端(ECS執行個體)可以串連執行個體的備可用性區域地址,並僅執行讀操作(如需執行寫操作,仍需串連主可用性區域地址)。代碼如下:

    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);
    
            // 配置備可用性區域串連地址、連接埠、帳號密碼資訊。
            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) {
                // 捕獲寫操作異常(如果誤操作執行了寫操作)。
                e.getMessage();
            }
            catch (Exception e) {
                // 逾時或其他異常處理。
                e.printStackTrace();
            }
            finally {
                if (jedis != null) {
                    jedis.close();
                }
            }
            pool.destroy();    // 當應用退出,需銷毀資源時,調用此方法。此方法會中斷連線、釋放資源。
        }
    }