全部產品
Search
文件中心

PolarDB:租戶隔離

更新時間:Mar 03, 2026

在多租戶業務情境下,部分“熱點租戶”因資料量或訪問量過高,會搶佔其所在節點的計算與儲存資源,影響同一節點上其他租戶的查詢效能。PolarDB PostgreSQL分布式版提供租戶隔離功能,允許您將指定租戶的資料線上遷移至獨立的節點,為其分配專用資源,從而徹底解決資源爭搶問題,保障所有租戶的效能與穩定性。

功能簡介

在標準的多租戶架構中,為最大化資源使用率,PolarDB PostgreSQL分布式版會將不同租戶的資料均勻分布在叢集的各個資料節點(DN)上。這意味著多個租戶會共用同一個節點的儲存和計算資源。

然而,當叢集中出現“熱點租戶”(通常指資料量或訪問負載遠超其他租戶的租戶)時,這種共用模式會引發一系列問題:

  • 資源爭用:熱點租戶的高頻查詢會過度消耗其所在節點的CPU、記憶體和I/O資源,導致同一節點上的其他鄰居租戶查詢效能顯著下降。

  • 效能抖動:熱點租戶的突發流量可能導致其他冷租戶的查詢延遲顯著增加,影響體驗。

  • 儲存失衡:熱點租戶的龐巨量資料量可能導致部分節點的儲存使用率遠高於其他節點,造成資源浪費和管理複雜性。

租戶隔離功能通過物理遷移資料的方式,為您提供解決上述問題的有效手段。您可以將熱點租戶的資料(分區或Schema)遷移到一個獨立的、資源富餘的節點上,實現資源隔離。

優勢

  • 專用資源保障:將熱點租戶隔離到專屬節點,避免其與其他租戶爭搶資源,確保核心業務的效能與穩定性。

  • 提升整體效能:通過均衡節點負載,消除資源瓶頸,從而提升整個叢集的服務效能和穩定性。

  • 線上平滑遷移:租戶隔離的資料移轉過程線上進行,對業務的讀寫操作(DML/DQL)無阻塞,不影響商務持續性。

  • 遷移策略靈活:您可以選擇將熱點租戶遷移到新節點,也可以選擇將節點上的其他冷租戶遷出,以騰出整個節點專用於熱點租戶。

注意事項

  • 在執行資料移轉期間,源節點和目標節點的資源負載(如CPU、IO、網路)會升高。建議您在業務低峰期執行此操作。

  • 在執行遷移前,請確保目標節點有足夠的儲存空間來容納待遷移的資料。

水平分割(基於分區)

對於按租戶ID(tenant_id)進行水平分割的表,您可以先為熱點租戶建立一個專屬分區,然後將該分區遷移至目標節點。

步驟一:建立租戶專屬分區

執行isolate_tenant_to_new_shard函數,為指定租戶的資料建立一個新的獨立分區。

文法

SELECT isolate_tenant_to_new_shard('<分布表名>', '<租戶ID>', 'CASCADE');

樣本

  1. 準備資料:

    CREATE TABLE orders (
        order_id     BIGSERIAL,          -- 訂單ID,自增
        store_id     INT NOT NULL,       -- 店鋪ID,將作為分布鍵(租戶ID)
        product_name VARCHAR(255),       -- 商品名稱
        amount       DECIMAL(10, 2),     -- 訂單金額
        order_time   TIMESTAMPTZ DEFAULT NOW(), -- 下單時間
        PRIMARY KEY (order_id, store_id) -- 注意:分布鍵必須是主鍵的一部分
    );
    
    -- 將'orders'表定義為分布式表,並以'store_id'列進行水平分割
    SELECT create_distributed_table('orders', 'store_id');
    
    -- 為店鋪101插入5條訂單
    INSERT INTO orders (store_id, product_name, amount)
    SELECT 101, '膝上型電腦 - ' || i, 4999.00 + i FROM generate_series(1, 5) i;
    
    -- 為店鋪102插入5條訂單
    INSERT INTO orders (store_id, product_name, amount)
    SELECT 102, '機械鍵盤 - ' || i, 899.00 + i FROM generate_series(1, 5) i;
  2. 執行命令:

    -- 樣本:為分布表't'中的租戶'101'建立隔離分區
    SELECT isolate_tenant_to_new_shard('orders', '102', 'CASCADE');
  3. 查看結果:
    函數會返回新建立的分區ID。

     isolate_tenant_to_new_shard
    -----------------------------
                          102108

    此時,ID為102108的分區已建立,但它仍位於原始節點上,需要執行下一步才能完成隔離。

步驟二:遷移分區至目標節點

執行polar_cluster_move_shard_placement函數,將上一步建立的專屬分區遷移至資源富餘的目標節點。您可以根據實際情況選擇以下任一策略。

文法

SELECT polar_cluster_move_shard_placement(
    <分區ID>, 
    '<源節點IP>',
    <源節點連接埠>, 
    '<目標節點IP>', 
    <目標節點連接埠>
 );

遷移策略

遷移熱點租戶分區

這是最直接的方式。將熱點租戶的專屬分區從當前節點移動到目標節點。

  1. 查詢熱點分區當前位置:

    -- 將102108替換為您在上一步擷取的分區ID
    SELECT nodename, nodeport FROM pg_dist_shard_placement WHERE shardid = 102108;

    查看結果:

    nodename  | nodeport
    ----------+----------
    10.0.0.1  |     5432
  2. 執行遷移命令:

    -- 樣本:將分區102108從10.0.0.1:5432遷移到10.0.0.2:5432
    SELECT polar_cluster_move_shard_placement(102108, '10.0.0.1', 5432, '10.0.0.2', 5432);

遷移非熱點租戶分區

如果您希望將當前節點完全釋放給熱點租戶,也可以將該節點上的其他所有非熱點分區遷移出去。

  1. 查詢熱點節點上的所有非熱點分區:

    -- 將102108替換為熱點分區ID,'10.0.0.1'和5432替換為熱點節點資訊
    SELECT shardid, shard_size
     FROM polar_cluster_shards
     WHERE table_name::text = 't' AND
           shardid <> 102108 AND
           nodename = '10.0.0.1' AND nodeport = 5432
     ORDER BY shard_size ASC, shardid ASC;

    查看結果:

     shardid | shard_size
    ---------+------------
      102104 |       8192
      102105 |      16384
      102106 |   83820544
      102107 |  256344064
  2. 逐個遷移非熱點分區:
    根據查詢結果,依次將這些分區遷移到目標節點。

    SELECT polar_cluster_move_shard_placement(102104, '10.0.0.1', 5432, '10.0.0.2', 5432);
    SELECT polar_cluster_move_shard_placement(102105, '10.0.0.1', 5432, '10.0.0.2', 5432);
    ...

垂直分割(基於Schema)

對於每個租戶的資料存放區在獨立Schema的垂直分割情境,隔離操作更為簡單。您只需將熱點租戶對應的整個Schema遷移到目標節點即可。

文法

SELECT polar_cluster_schema_move(
    '<Schema名稱>', 
    '<目標節點IP>', 
    <目標節點連接埠>
);

樣本

  1. 準備資料:

    -- 新的SCHEMA company1
    CREATE SCHEMA company1;
    
    -- 定義一個分布式Schema
    SELECT polar_cluster_schema_distribute('company1');
    
    -- 建立測試表
    CREATE TABLE company1.users (id SERIAL, name TEXT);
  2. 從以下SELECT語句查詢計劃樣本可以看出,特定租戶的查詢只會訪問特定節點(計劃中表明,唯一要訪問的DN節點為10.0.0.1:5432):

    EXPLAIN SELECT * FROM company1.users WHERE id = 1;
                                       QUERY PLAN
    --------------------------------------------------------------------------------
     Custom Scan (PolarCluster Adaptive)  (cost=0.00..0.00 rows=0 width=0)
       Task Count: 1
       Tasks Shown: All
       ->  Task
             Node: host=10.0.0.1 port=5432 dbname=postgres
             ->  Seq Scan on users_102010 users  (cost=0.00..25.88 rows=6 width=36)
                   Filter: (id = 1)
  3. 使用polar_cluster_schema_move函數執行遷移。

    -- 樣本:將Schema 'company1'遷移到節點10.0.0.2:5432
    SELECT polar_cluster_schema_move('company1', '10.0.0.2', 5432);