本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
决策矩阵
要决定应在 PostgreSQL 中使用哪种多租户 SaaS 分区模型,请查阅以下决策矩阵。该矩阵分析了这四个分区选项:
-
Silo-每个租户具有单独的 PostgreSQL 实例或集群。
-
使用不同的数据库进行桥接-单个 PostgreSQL 实例或集群中的每个租户都有一个单独的数据库。
-
使用不同的架构进行桥接 — 单个 PostgreSQL 数据库、单个 PostgreSQL 实例或集群中每个租户的单独架构。
-
池 — 在单个实例和架构中为租户共享表。
筒仓 | 使用单独的数据库进行桥接 | 使用单独的架构进行桥接 | 池 | |
---|---|---|---|---|
使用案例 | 隔离数据并完全控制资源使用是一项关键要求,否则您的租户非常庞大且对性能非常敏感。 | 数据隔离是一项关键要求,需要对租户的数据进行有限的交叉引用,或者不需要交叉引用。 | 租户数量适中,数据量适中。如果您必须交叉引用租户的数据,这是首选模型。 | 大量租户,每个租户的数据较少。 |
新租户入职灵活性 | 非常低。(每个租户都需要一个新的实例或集群。) | 中度地减少固定。(需要为每个租户创建一个新数据库来存储架构对象。) | 中度地减少固定。(需要为每个租户创建一个新架构来存储对象。) | 最快的选项。(需要最低限度的设置。) |
数据库连接池配置工作量和效率 | 需要付出大量努力。(每个租户一个连接池。) 效率低。(租户之间不共享数据库连接。) |
需要付出大量努力。(除非您使用 Amazon RDS 代理,否则每个租户只能配置一个连接池。) 效率低。(租户和连接总数之间不共享数据库连接。 所有租户的使用量取决于数据库实例类。) |
所需的工作量更少。(适用于所有租户的一个连接池配置。) 效率适中。(仅在会话池模式下通过 |
只需最少的精力。 最高限度地减少固定 (一个连接池供所有租户使用,并在所有租户之间高效地重复使用连接。 数据库连接限制取决于数据库实例类。) |
数据库维护(真空管理 |
更限度地减少管理。 | 中等复杂性。(可能会导致大量资源消耗,因为之后vacuum_naptime 必须为每个数据库启动真空工作器,这会导致自动真空启动器的 CPU 使用率很高。 清理每个数据库的 PostgreSQL 系统目录表也可能会带来额外的开销。) |
大型的 PostgreSQL 系统目录表。(总pg_catalog 规模以数十GB为单位,具体取决于租户数量和亲属关系。 可能需要修改与真空相关的参数才能控制工作台膨胀。) |
表可能很大,具体取决于租户数量和每个租户的数据。(可能需要修改与真空相关的参数才能控制工作台膨胀。) |
扩展管理工作 | 付出了巨大的努力(针对不同实例中的每个数据库)。 | 大量工作(在每个数据库级别)。 | 工作量最小(在通用数据库中一次)。 | 工作量最小(在通用数据库中一次)。 |
更改部署工作 | 重大限度地减少固定 (Connect 每个单独的实例并发布更改。) | 重大限度地减少固定 (Connect 每个数据库和架构,然后发布更改。) | 适度努力。(Connect 通用数据库并发布每个架构的更改。) | 最少的努力。(Connect 通用数据库并发布更改。) |
变更部署 — 影响范围 | 最低。(单个租户受到影响。) | 最低。(单个租户受到影响。) | 最低。(单个租户受到影响。) | 非常大。(所有租户都受到影响。) |
查询绩效管理和工作 | 可管理的查询性能。 | 可管理的查询性能。 | 可管理的查询性能。 | 要保持查询性能,可能需要付出大量努力。(随着时间的推移,由于表的大小增加,查询的运行速度可能会变慢。 您可以使用表分区和数据库分片来保持性能。) |
跨租户资源影响 | 没有影响。(租户之间不共享资源。) | 中度地减少影响。(租户共享常用资源,例如实例 CPU 和内存。) | 中度地减少影响。(租户共享常用资源,例如实例 CPU 和内存。) | 重度地减少固定。(租户在资源、锁定冲突等方面相互影响。) |
租户级别的调整(例如,为每个租户创建其他索引或为特定租户调整数据库参数) | 可能的。 | 可能的原因。(可以对每个租户进行架构级别的更改,但数据库参数在所有租户中都是全局性的。) | 可能的原因。(可以对每个租户进行架构级别的更改,但数据库参数在所有租户中都是全局性的。) | 不可能的。(桌子由所有租户共享。) |
为对绩效敏感的租户进行再平衡工作 | 最低。(无需再平衡。 扩展服务器和 I/O 资源以处理这种情况。) | 中。(使用逻辑复制或导pg_dump 出数据库,但停机时间可能会很长,具体取决于数据大小。 您可以使用 Amazon RDS for PostgreSQL 中的可传输数据库功能在实例之间更快地复制数据库。) |
中等,但可能涉及长时间的停机时间。(使用逻辑复制或导pg_dump 出架构,但停机时间可能会很长,具体取决于数据大小。) |
意义重大,因为所有租户共享相同的桌子。(对数据库进行分片需要将所有内容复制到另一个实例,另外还需要一个步骤来清理租户数据。) 很可能需要更改应用程序逻辑。 |
主要版本升级导致数据库停机 | 标准停机时间。(取决于 PostgreSQL 系统目录的大小。) | 停机时间可能会更长。(根据系统目录的大小,时间会有所不同。 PostgreSQL 系统目录表也在数据库之间复制) | 停机时间可能会更长。(根据 PostgreSQL 系统目录的大小,时间会有所不同。) | 标准停机时间。(取决于 PostgreSQL 系统目录的大小。) |
管理开销(例如,用于数据库日志分析或备份作业监控) | 重大努力 | 最少的努力。 | 最少的努力。 | 最少的努力。 |
租户级别的可用性 | 最低。(每个租户都失败并独立恢复。) | 影响范围更大。(如果出现硬件或资源问题,所有租户都会出现故障并一起恢复。) | 影响范围更大。(如果出现硬件或资源问题,所有租户都会出现故障并一起恢复。) | 影响范围更大。(如果出现硬件或资源问题,所有租户都会出现故障并一起恢复。) |
租户级别的备份和恢复工作 | 最限度地减少固定 (每个租户可以单独备份和还原。) | 适度努力。(对每个租户使用逻辑导出和导入。 需要进行一些编码和自动化。) | 适度努力。(对每个租户使用逻辑导出和导入。 需要进行一些编码和自动化。) | 重大限度地减少固定 (所有租户共享相同的桌子。) |
租户级别的 point-in-time 恢复工作 | 最少的努力。(使用快照使用点对点时间恢复,或者在 Amazon Aurora 中使用回溯功能。) | 适度努力。(使用快照恢复,然后使用导出/导入。 但是,这将是一个缓慢的操作。) | 适度努力。(使用快照恢复,然后使用导出/导入。 但是,这将是一个缓慢的操作。) | 工作量大,复杂程度高。 |
统一架构名称 | 每个租户具有相同的架构名称。 | 每个租户具有相同的架构名称。 | 每个租户具有不同的架构。 | 通用架构。 |
按租户自定义(例如,特定租户的附加表列) | 可能的。 | 可能的。 | 可能的。 | 复杂(因为所有租户共享相同的表)。 |
对象关系映射 (ORM) 层(例如 Ruby)的目录管理效率 | 高效(因为客户端连接是特定于租户的)。 | 高效(因为客户端连接特定于数据库)。 | 效率适中。(根据所使用的 ORM、用户/角色安全模型和search_path 配置,客户端有时会缓存所有租户的元数据,从而导致数据库连接内存使用率过高。) |
高效(因为所有租户共享相同的桌子)。 |
合并租户报告工作 | 重大限度地减少固定 (您必须使用外部数据包装器 [FDW] 来整合所有租户中的数据,或者提取、转换 [ETL] 并将其加载到另一个报告数据库。) | 重大限度地减少固定 (您必须使用 FDW 将所有租户或 ETL 中的数据合并到另一个报告数据库。) | 适度努力。(您可以使用联合来聚合所有架构中的数据。) | 最少的努力。(所有租户数据都在同一个表中,因此报告很简单。) |
租户特定的只读报告实例(例如,基于订阅) | 最限度地减少固定 (创建只读副本。) | 适度努力。(您可以使用逻辑复制或DatAWS abase 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 列数。) |