

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# PostgreSQL 的多租戶 SaaS 分割模型


完成多租戶的最佳方法取決於 SaaS 應用程式的需求。下列各節示範在 PostgreSQL 中成功實作多租用戶的分割模型。

**注意**  
本節討論的模型適用於 Amazon RDS for PostgreSQL 和 Aurora PostgreSQL 相容。本節中 *PostgreSQL* 的參考適用於這兩個 服務。

您可以在 PostgreSQL for SaaS 分割中使用三種高階模型：孤立、橋接和集區。下圖摘要說明孤立和集區模型之間的權衡。橋接器模型是孤立和集區模型的混合。


****  

| **分割模型** | **優點** | **缺點** | 
| --- | --- | --- | 
| 孤立 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | 
| 集區 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | 
| 橋接器 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | 

以下各節會更詳細地討論每個模型。

**Topics**
+ [

# PostgreSQL 孤立模型
](silo.md)
+ [

# PostgreSQL 集區模型
](pool.md)
+ [

# PostgreSQL 橋接器模型
](bridge.md)
+ [

# 決策矩陣
](matrix.md)

# PostgreSQL 孤立模型


孤立模型是透過為應用程式中的每個租用戶佈建 PostgreSQL 執行個體來實作。孤立模型在租戶效能和安全性隔離方面表現卓越，並完全消除*雜訊鄰近*現象。當一個租用戶使用系統影響另一個租用戶的效能時，就會發生雜訊鄰近現象。孤島模型可讓您專門針對每個租用戶量身打造效能，並可能將中斷限制為特定租用戶的孤島。不過，推動採用孤立模型的因素通常是嚴格的安全和法規限制。SaaS 客戶可以鼓勵這些限制條件。例如，由於內部限制，SaaS 客戶可能會要求隔離其資料，而 SaaS 供應商可能會提供此類服務，但需額外付費。

 ![\[SaaS PostgreSQL silo model\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/images/saas-postgresql-silo.png) 

雖然在某些情況下可能需要孤立模型，但它有許多缺點。通常很難以經濟實惠的方式使用孤立模型，因為跨多個 PostgreSQL 執行個體管理資源消耗可能會很複雜。此外，此模型中資料庫工作負載的分散式本質使得維護租用戶活動的集中檢視更為困難。管理這麼多獨立操作的工作負載會增加營運和管理開銷。孤立模型也會讓租戶加入更加複雜且耗時，因為您必須佈建租戶特定的資源。此外，整個 SaaS 系統可能更難以擴展，因為租用戶特定的 PostgreSQL 執行個體數量不斷增加，需要更多操作時間來管理。最後一項考量是，應用程式或資料存取層必須維護租用戶與其相關聯 PostgreSQL 執行個體的映射，這會增加實作此模型的複雜性。

# PostgreSQL 集區模型


集區模型的實作方式是佈建單一 PostgreSQL 執行個體 (Amazon RDS 或 Aurora)，並使用[資料列層級安全性 (RLS)](https://aws.amazon.com/blogs/database/multi-tenant-data-isolation-with-postgresql-row-level-security/) 來維護租戶資料隔離。RLS 政策會限制`SELECT`查詢傳回資料表中的哪些資料列`UPDATE`，或哪些資料列會受到 `INSERT`、 和 `DELETE`命令的影響。集區模型會將所有租用戶資料集中在單一 PostgreSQL 結構描述中，因此更符合成本效益，且需要較少的操作開銷才能維護。監控此解決方案也會因為其集中化而更加簡單。不過，在集區模型中監控租戶特定的影響，通常需要在應用程式中進行一些額外的檢測。這是因為 PostgreSQL 預設不知道哪個租用戶正在耗用資源。租戶加入已簡化，因為不需要新的基礎設施。這種靈活性可讓您更輕鬆地完成快速且自動化的租戶加入工作流程。

 ![\[SaaS PostgreSQL pool model\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/images/saas-postgresql-pool.png) 

雖然集區模型通常更具成本效益且更容易管理，但確實有一些缺點。在集區模型中，無法完全消除雜訊鄰近現象。不過，透過確保 PostgreSQL 執行個體上提供適當的資源，以及使用策略來減少 PostgreSQL 中的負載，例如將查詢卸載至僅供讀取複本或卸載至 Amazon ElastiCache，可以緩解此問題。有效的監控也在回應租戶效能隔離問題方面扮演重要角色，因為應用程式檢測可以記錄和監控租戶特定的活動。最後，某些 SaaS 客戶可能找不到 RLS 提供的邏輯分隔足夠，並可能要求額外的隔離措施。

# PostgreSQL 橋接器模型


PostgreSQL 橋接器模型是混合和孤立方法的組合。如同集區模型，您可以為每個租用戶佈建單一 PostgreSQL 執行個體。若要維持租戶資料隔離，請使用 PostgreSQL 邏輯建構。在下圖中，PostgreSQL 資料庫用於邏輯上分隔資料。

**注意**  
PostgreSQL 資料庫不是指單獨的 Amazon RDS for PostgreSQL 或 Aurora PostgreSQL 相容資料庫執行個體。而是參考 PostgreSQL 資料庫管理系統的邏輯建構來分隔資料。

 ![\[SaaS PostgreSQL bridge model with separate databases\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/images/saas-postgresql-bridge-dbs.png) 

您也可以使用單一 PostgreSQL 資料庫搭配每個資料庫中的租戶特定結構描述來實作橋接模型，如下圖所示。

 ![\[SaaS PostgreSQL bridge model with separate schemas\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/images/saas-postgresql-bridge-schemas.png) 

橋接器模型受到與集區模型相同的雜訊鄰近和租戶效能隔離考量。它也會產生一些額外的操作和佈建額外負荷，方法是要求每個租用戶佈建個別的資料庫或結構描述。它需要有效的監控才能快速回應租戶效能問題。它還需要應用程式檢測來監控租戶特定的用量。整體而言，橋樑模型可以視為 RLS 的替代方案，透過需要新的 PostgreSQL 資料庫或結構描述來稍微增強租戶加入工作。如同孤島模型，應用程式或資料存取層必須維護租用戶與其相關聯 PostgreSQL 資料庫或結構描述的映射。

# 決策矩陣


若要決定您應該搭配 PostgreSQL 使用的多租戶 SaaS 分割模型，請參閱下列決策矩陣。矩陣會分析這四個分割選項：
+ Silo – 每個租用戶的個別 PostgreSQL 執行個體或叢集。
+ 與個別資料庫橋接 – 單一 PostgreSQL 執行個體或叢集中每個租用戶的個別資料庫。
+ 與個別結構描述橋接 – 單一 PostgreSQL 執行個體或叢集中單一 PostgreSQL 資料庫中每個租用戶的個別結構描述。
+ 集區 – 單一執行個體和結構描述中租用戶的共用資料表。


****  

| **** | **孤立** | **與個別資料庫橋接** | **使用個別結構描述橋接** | **集區** | 
| --- | --- | --- | --- | --- | 
| 使用案例 | 完全控制資源用量的資料隔離是一項關鍵要求，或者您有非常大且非常重視效能的租戶。 | 資料隔離是關鍵要求，而且需要有限或不需要租用戶資料的交叉參考。 | 具有中等資料量的中等租用戶數量。如果您必須跨參考租用戶的資料，這是偏好的模型。 | 每個租用戶的資料較少的大量租用戶。 | 
| 新租戶加入敏捷性 | 非常慢。（每個租用戶都需要新的執行個體或叢集。) | 中度緩慢。（需要為每個租用戶建立新的資料庫，以存放結構描述物件。) | 中度緩慢。（需要為每個租用戶建立新的結構描述來存放物件。) | 最快選項。（需要最低設定。) | 
| 資料庫連線集區組態工作量和效率 | 需要大量努力。（每個租用戶一個連線集區。) 效率較低。（租用戶之間沒有資料庫連線共用。)  | 需要大量努力。（除非您使用 [Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html)，否則每個租用戶一個連線集區組態。)  效率較低。（租用戶與連線總數之間沒有資料庫連線共用。 所有租用戶的使用量會根據資料庫執行個體類別而受到限制。) | 需要的精力較少。（適用於所有租用戶的一個連線集區組態。)  效率適中。（僅在工作階段集區模式中透過 `SET ROLE`或 `SET SCHEMA`命令重複使用連線。使用 Amazon RDS Proxy 時， `SET`命令也會導致工作階段鎖定，但可以消除用戶端連線集區，並且可以為每個請求進行直接連線以提高效率。) | 需要最少的努力。 最有效率。（適用於所有租用戶的一個連線集區，以及適用於所有租用戶的高效連線重複使用。 資料庫連線限制是以資料庫執行個體類別為基礎。) | 
| 資料庫維護 ([清空管理](https://www.postgresql.org/docs/current/routine-vacuuming.html)) 和資源使用量 | 更簡單的管理。 | 中等複雜性。（可能會導致高資源耗用量，因為在 之後，必須為每個資料庫啟動清空工作者vacuum\$1naptime，這會導致高自動清空啟動器 CPU 用量。 清空每個資料庫的 PostgreSQL 系統目錄資料表也可能產生額外的額外負荷。) | 大型 PostgreSQL 系統目錄資料表。（總pg\$1catalog大小，以十 GBs 為單位，取決於租戶和關係的數量。 可能需要修改清空相關參數，以控制資料表膨脹。) | 資料表可能很大，取決於每個租用戶的租用戶數量和資料。（可能需要修改清空相關參數，以控制資料表膨脹。) | 
| 延伸模組管理工作 | 大量努力 （針對個別執行個體中的每個資料庫）。 | 大量努力 （在每個資料庫層級）。 | 最小努力 （在通用資料庫中一次）。 | 最小努力 （在通用資料庫中一次）。 | 
| 變更部署工作 | 大量努力。（連接至每個個別執行個體並推出變更。) | 大量努力。（連接至每個資料庫和結構描述，並推出變更。) | 中度努力。（連接至通用資料庫並推出每個結構描述的變更。) | 最少的努力。（連接至通用資料庫並推出變更。) | 
| 變更部署 – 影響範圍 | 最小。（單一租戶受影響。) | 最小。（單一租戶受影響。) | 最小。（單一租戶受影響。) | 非常大。（受影響的所有租戶。) | 
| 查詢效能管理和工作 | 可管理的查詢效能。 | 可管理的查詢效能。 | 可管理的查詢效能。 | 可能需要大量精力來維持查詢效能。（隨著時間的推移，由於資料表大小增加，查詢執行速度可能會變慢。 您可以使用資料表分割和資料庫碎片來維持效能。) | 
| 跨租用戶資源影響 | 沒有影響。（租用戶之間沒有資源共用。) | 中度影響。（租用戶共用常見的資源，例如執行個體 CPU 和記憶體。) | 中度影響。（租用戶共用常見的資源，例如執行個體 CPU 和記憶體。) | 嚴重影響。（租用戶在資源、鎖定衝突等方面互相影響。) | 
| 租用戶層級調校 （例如，為每個租用戶建立其他索引，或針對特定租用戶進行資料庫參數調校） | 可能。 | 有些可能。（可以為每個租用戶進行結構描述層級變更，但資料庫參數適用於所有租用戶。) | 有些可能。（可以為每個租用戶進行結構描述層級變更，但資料庫參數適用於所有租用戶。) | 無法。（所有租用戶都會共用資料表。) | 
| 效能敏感租用戶的重新平衡工作 | 最小。（不需要重新平衡。 擴展伺服器和 I/O 資源以處理此案例。) | 中等。（使用邏輯複寫或 pg\$1dump 匯出資料庫，但停機時間可能會很長，具體取決於資料大小。 您可以使用 Amazon RDS for PostgreSQL 中的可傳輸資料庫功能，更快速地在執行個體之間複製資料庫。) | 中等但可能涉及長時間的停機時間。（使用邏輯複寫或 pg\$1dump 匯出結構描述，但停機時間可能會很長，具體取決於資料大小。) | 重要，因為所有租用戶共用相同的資料表。（碎片資料庫需要將所有項目複製到另一個執行個體，以及清除租戶資料的額外步驟。)  最可能需要變更應用程式邏輯。 | 
| 主要版本升級的資料庫停機時間 | 標準停機時間。（取決於 PostgreSQL 系統目錄大小。) | 停機時間可能較長。（視系統目錄大小而定，時間會有所不同。 PostgreSQL 系統目錄資料表也會跨資料庫複製） | 停機時間可能較長。（視 PostgreSQL 系統目錄大小而定，時間會有所不同。) | 標準停機時間。（取決於 PostgreSQL 系統目錄大小。) | 
| 管理開銷 （例如，用於資料庫日誌分析或備份任務監控） | 大量努力 | 最少的努力。 | 最少的努力。 | 最少的努力。 | 
| 租戶層級可用性 | 最高。（每個租戶都會失敗並獨立復原。) | 影響範圍更高。（如果發生硬體或資源問題，所有租戶都會失敗並一起復原。) | 影響範圍更高。（如果發生硬體或資源問題，所有租戶都會失敗並一起復原。) | 影響範圍更高。（如果發生硬體或資源問題，所有租戶都會失敗並一起復原。) | 
| 租戶層級備份和復原工作 | 最少的努力。（每個租用戶都可以獨立備份和還原。) | 中度努力。（為每個租用戶使用邏輯匯出和匯入。 需要一些編碼和自動化。) | 中度努力。（為每個租用戶使用邏輯匯出和匯入。 需要一些編碼和自動化。) | 大量努力。（所有租用戶共用相同的資料表。) | 
| 租戶層級point-in-time復原工作 | 最少的努力。（使用快照來使用時間點復原，或在 Amazon Aurora 中使用恢復。) | 中度努力。（使用快照還原，後面接著匯出/匯入。 不過，這會是慢速操作。) | 中度努力。（使用快照還原，後面接著匯出/匯入。 不過，這會是慢速操作。) | 大量的精力和複雜性。 | 
| 統一結構描述名稱 | 每個租用戶的相同結構描述名稱。 | 每個租用戶的相同結構描述名稱。 | 每個租用戶的不同結構描述。 | 常見結構描述。 | 
| 每個租用戶自訂 （例如，特定租用戶的其他資料表資料欄） | 可能。 | 可能。 | 可能。 | 複雜 （因為所有租用戶共用相同的資料表）。 | 
| 物件關聯映射 (ORM) 層的目錄管理效率 （例如 Ruby) | 有效率 （因為用戶端連線專屬於租用戶）。 | 有效率 （因為用戶端連線專屬於資料庫）。 | 效率適中。（根據使用的 ORM、使用者/角色安全模型和search\$1path組態，用戶端有時會快取所有租用戶的中繼資料，導致高資料庫連線記憶體用量。) | 有效率 （因為所有租用戶共用相同的資料表）。 | 
| 合併租戶報告工作 | 大量努力。（您必須使用外部資料包裝函式 【FDWs】 來合併所有租用戶中的資料，或擷取、轉換和載入 【ETL】 至另一個報告資料庫。) | 大量努力。（您必須使用 FDWs將所有租戶或 ETL 中的資料合併到另一個報告資料庫。) | 中度努力。（您可以使用聯集彙總所有結構描述中的資料。) | 最少的努力。（所有租戶資料都在相同的資料表中，因此報告很簡單。) | 
| 用於報告的租戶特定唯讀執行個體 （例如，根據訂閱） | 最少的努力。（建立僅供讀取複本。) | 中度努力。（您可以使用邏輯複寫或 AWS Database Migration Service 【AWS DMS】 進行設定。) | 中度努力。（您可以使用邏輯複寫或 AWS DMS 進行設定。) | 複雜 （因為所有租用戶共用相同的資料表）。 | 
| 資料隔離 | 最佳。 | 更好。（您可以使用 PostgreSQL 角色管理資料庫層級許可。) | 更好。（您可以使用 PostgreSQL 角色管理結構描述層級許可。) | 更差。（由於所有租用戶共用相同的資料表，您必須實作功能，例如用於租用戶隔離的資料列層級安全 【RLS】)。 | 
| 租用戶特定的儲存加密金鑰 | 可能。（每個 PostgreSQL 叢集可以有自己的 AWS Key Management Service 【AWS KMS】 金鑰進行儲存加密。) | 無法。（所有租用戶共用相同的 KMS 金鑰以進行儲存加密。) | 無法。（所有租用戶共用相同的 KMS 金鑰以進行儲存加密。) | 無法。（所有租用戶共用相同的 KMS 金鑰以進行儲存加密。) | 
| 針對每個租用戶使用 AWS Identity and Access Management (IAM) 進行資料庫身分驗證 | 可能。 | 可能。 | 可能 （每個結構描述都有個別的 PostgreSQL 使用者）。 | 無法 （因為所有租用戶都會共用資料表）。 | 
| 基礎設施成本 | 最高 （因為沒有共用）。 | 中等。 | 中等。 | 最低。 | 
| 資料重複和儲存用量 | 所有租用戶的最高彙總。(PostgreSQL 系統目錄資料表和應用程式的靜態和常用資料會在所有租用戶間複製。) | 所有租用戶的最高彙總。(PostgreSQL 系統目錄資料表和應用程式的靜態和常用資料會在所有租用戶間複製。) | 中等。（應用程式的靜態和常用資料可以位於常見的結構描述中，並由其他租戶存取。) | 最小。（不複製資料。 應用程式的靜態和常用資料可以位於相同的結構描述中。) | 
| 以租用戶為中心的監控 （快速找出哪些租用戶造成問題） | 最少的努力。（因為個別監控每個租用戶，所以很容易檢查特定租用戶的活動。) | 中度努力。（由於所有租用戶共用相同的實體資源，您必須套用額外的篩選來檢查特定租用戶的活動。) | 中度努力。（由於所有租用戶共用相同的實體資源，您必須套用額外的篩選來檢查特定租用戶的活動。) | 大量努力。（由於所有租用戶共用所有資源，包括資料表，您必須使用繫結變數擷取來檢查特定 SQL 查詢所屬的租用戶。) | 
| 集中式管理和運作狀態/活動監控 | 大量努力 （設定中央監控和中央命令中心）。 | 中等努力 （因為所有租戶共用相同的執行個體）。 | 中等努力 （因為所有租戶共用相同的執行個體）。 | 盡可能減少工作量 （因為所有租戶共用相同的資源，包括結構描述）。 | 
| 物件識別符 (OID) 和交易 ID (XID) 包圍的機率 | 最小。 | 高。（因為 OID，XID 是單一 PostgreSQL 全叢集計數器，因此在實體資料庫之間有效清空可能會有問題）。 | 中等。（因為 OID，XID 是單一 PostgreSQL 叢集整體計數器）。 | 高。（例如，單一資料表可以達到 40 億 TOAST OID 限制，取決於out-of-line資料欄的數量。) | 