在多租戶應用中,因廣播查詢導致的效能下降或資料分布不均造成的資源浪費是常見問題。PolarDB PostgreSQL分布式版提供原生的多租戶管理能力,支援水平分割(Row-based Sharding)和垂直分割(Schema-based Sharding)兩種模式。該能力可將特定租戶的查詢請求精確路由到單個DN節點,避免廣播查詢,實現高效讀寫。同時通過均衡租戶資料分布,防止資料扭曲,提升資源使用率。
方案對比與選擇
根據業務情境和資料特點,選擇合適的拆分策略。兩種策略的核心目標都是將單個租戶的請求與資料鎖定在單個DN節點上,以獲得最佳效能。
模式 | 說明 | 推薦情境 |
水平分割(Row-based Sharding) | 在同一張表中通過租戶ID欄位(分布列)區分資料,並將不同租戶的資料行分布到不同DN節點。 |
|
垂直分割(Schema-based Sharding) | 為每個租戶建立獨立的Schema,並將整個Schema的資料定向分布到特定DN節點。 |
|
水平分割
通過將租戶ID列指定為分布列,實現按行(Row-based)的租戶資料隔離。
步驟一:建立分布表
建立一張包含租戶ID列(例如tenant_id)的表,並調用create_distributed_table函數將其轉換為以該列為分布鍵的分布表。
-- 1. 建立表,其中 tenant_id 是用於區分租戶的列。
CREATE TABLE test_table (tenant_id text primary key, data text);
-- 2. 將表 test_table 設定為分布表,並指定 tenant_id 為分布列。
SELECT create_distributed_table('test_table', 'tenant_id');步驟二:驗證查詢路由
執行針對特定租戶的查詢,並查看其查詢計劃,以驗證請求是否被精確路由到單個DN節點。在返回的查詢計劃中,若Task Count為1,則表明查詢已成功下推到單個DN節點(樣本中節點為10.0.0.1:5432),避免了廣播查詢。
-- 查看針對租戶 'company1' 的查詢計劃。
EXPLAIN SELECT * FROM test_table WHERE tenant_id = 'company1';
-- 返回結果樣本:
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=testdb
-> Index Scan using test_table_pkey_102185 on test_table_102185 test_table (cost=0.15..2.37 rows=1 width=64)
Index Cond: (tenant_id = 'company1'::text)
(7 rows)垂直分割
通過為每個租戶建立獨立的分布式Schema,實現按Schema的租戶資料隔離。
步驟一:建立並分布Schema
為單個租戶(例如 company_test_1)建立一個專屬的Schema,並將其設定為分布式Schema。此操作會將該Schema下的所有資料和操作都定向到單個DN節點。
-- 1. 為租戶 company_test_1 建立 Schema。
CREATE SCHEMA company_test_1;
-- 2. 將該 Schema 設定為分布式 Schema。
SELECT polar_cluster_schema_distribute('company_test_1');步驟二:在租戶Schema下建立表
將搜尋路徑(search_path)切換到目標租戶的Schema,然後在該Schema下建立業務表。
-- 1. 切換到租戶 company_test_1 的 Schema。
SET search_path TO company_test_1;
-- 2. 在該 Schema 下建立業務表。
CREATE TABLE users (id SERIAL, name TEXT);
CREATE TABLE orders (id SERIAL, user_id INT);步驟三:驗證查詢路由
在指定租戶的search_path下,執行查詢並查看其查詢計劃,以驗證請求是否被路由到單個DN節點。在返回的查詢計劃中,若Task Count為1,則表明針對該租戶的所有操作都已隔離在單個節點內(樣本中節點為10.0.0.1:5432)。
-- 1. 確保 search_path 已設定為目標租戶。
SET search_path TO company_test_1;
-- 2. 查看查詢計劃。
EXPLAIN SELECT * FROM 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=testdb
-> Seq Scan on users_102191 users (cost=0.00..25.88 rows=6 width=36)
Filter: (id = 1)
(7 rows)