PROD欧洲主权BaaS平台打开仪表板 →

性能 · 11 最小读取值

专用数据库与共享数据库:性能和隔离

Affane Daylami · Fondateur · 2026年5月31日

返回博客

共享数据库并不意味着您的数据与其他客户端的数据混合。这意味着您的数据库运行在与其他数据库共享的 Postgres 服务器上。所以真正的问题不是“我的数据是否被隔离?” » 但“我的资源是吗?”即使每个租户都有自己的数据库、自己的表和自己的策略,CPU、内存、连接和磁盘吞吐量也会因为邻居的噪音而降低。

该英文文本是根据法文原文自动生成的,尚未经过审查。
该页面已自动翻译。英文版具有权威性。

本文比较了记录最多的 Postgres 租赁模型(共享模式、每个租户基础、专用集群,也称为每个租户数据库与共享数据库),解释了 noisy neighbor机制,然后详细介绍了 Aurabase 如何实现自己的两层模型,并在配置程序代码中进行验证。有关我们在发布性能数据之前应用的方法,请参阅我们的 后端基准测试方法。

如果您正在寻找两个客户端(RLS、策略、service_role)之间的数据泄漏问题,这不是本文的角度:我们的 RLS 比较和项目 的专用数据库详细介绍了这种逻辑隔离。这里,我们讨论的是物理资源:CPU、IO、连接、缓存。

要点

  • 共享数据库不一定是共享方案:Aurabase 通过仅共享集群为每个项目提供自己的 Postgres 数据库,即使在其标准级别也是如此。
  • noisy neighbor 会降低物理资源(CPU、IOPS、连接、autovacuum),而不是数据机密性:RLS 无法解决它,这不是它的作用。
  • Aurabase 配置程序恰好路由到两种架构,并在代码中进行了验证:FullyDedicated(为项目保留的整个 CNPG 集群,企业级)或 SharedClusterDedicated(基于组织的 CNPG 集群的专用基础,从不与其他组织共享)。
  • Aurabase 队列集群的默认观察容量阈值为每个集群 1000 个基地,可配置,超过该阈值建议迁移到专用集群。
  • 正确的选择取决于您的实际限制(合规性、流量可预测性、预算),而不是“专用总是更好”的条件反射。
#
型号

三种 Postgres 管理模型,从最共享到最隔离

微软关于多租户SaaS应用程序架构的官方文档区分了三种租户模型,通常称为Silo(每个租户专用资源)、Pool(完全共享资源)和Bridge(两者的混合体,一些是独立的租户,另一些是共享的)。这三个模型在模式、数据库或整个集群级别直接应用于 Postgres。

具体来说,对于 Postgres 后端,这提供了三种不同的架构。共享模式(单个基础、tenant_id列、过滤行的 RLS 策略)是多租户指南中最常见的池模型:经济,但两个客户端之间的边界变成了逐表计算的 SQL 表达式。共享集群上每个租户的基础是中间 Bridge 模型:每个租户都有自己的 Postgres 基础(真正的 CREATE DATABASE命令),但多个基础共存于同一个物理集群上,因此共享 CPU、IO 和连接。每个租户完全专用的集群是完整的筒仓模型:完全隔离的 CPU、RAM 和 IO 资源,通常为具有高合规性或负载问题的租户保留。

型号资源隔离储存保温运营努力
共享架构(tenant_id + RLS)无无(公共表)最小(1 个运行基地)
每个租户基础上,共享集群部分(集群CPU/IO)总计(自己的基础)中等(N 个碱基,1 个簇)
每个租户完全专用的集群总计总计高(每个租户 1 个集群)

Silo / Pool / Bridge 术语:微软官方文档,多租户 SaaS 架构模式(Azure 架构中心)。

指南中通常缺少基于共享集群上的每个租户的中间模型,这些指南将“每个人的单一基础”和“每个客户端一个服务器”之间的选择呈现为二元。然而,这是 Aurabase 默认使用的,详细信息如下。

这三种模型之间的选择取决于每个多租户架构决策,而不仅仅是 BaaS 提供商:在托管 Postgres(RDS、Cloud SQL 或自托管实例)上构建自己的 SaaS 后端的团队会进行完全相同的仲裁,一旦多个客户端被放置在同一个物理实例上,就会使用相同的争用机制。

#
机制

吵闹的邻居:资源共享时情况会恶化

noisy neighbor(吵闹的邻居)是消耗不成比例的基础设施共享资源的租户,从而损害同一服务器上的其他租户。该术语来自公共云,但直接适用于共享 Postgres 集群:一个数据库可以降低其他数据库的性能,而无需触及其他数据库的数据。

生产中最常出现的六种机制:

  • CPU 争用:昂贵的查询(无索引联接、大规模排序)会消耗内核在集群中所有活动数据库之间共享的 CPU 周期。
  • IOPS 争用:备份、VACUUM FULL 或大量导入会使集群的磁盘吞吐量饱和,从而减慢对其他数据库的读取和写入速度。
  • 连接耗尽: max_connections 限制整个集群级别的活动连接数量,而不是每个基地。开放过多的基地会降低其他基地的利润。
  • Autovacuum 争用:autovacuum 运行时每个集群的工作线程数量有限;具有高写入率的数据库可能会延迟清理另一个数据库的表。
  • 缓存驱逐: shared_buffers 是整个集群的单个内存;具有较大工作集的数据库可以逐出较小相邻数据库的缓存页面。
  • 共享维护时段:备份、副本故障转移或主要升级适用于整个集群,而不是基于每个基地。
与四个项目共享的集群与专用于单个项目的集群在左侧,共享 CNPG 集群托管四个基地(项目 A 到 D),它们全部汇聚到同一个 CPU、IOPS 和共享连接池,因此它们之间可能存在争用。右侧,一个专用 CNPG 集群仅托管一个项目,保留 CPU、IOPS 和连接,因此不可能出现外部争用。共享集群项目A项目B项目C项目DCPU·共享IOPS共享连接A、B、C、D 之间可能存在争用专用集群你的项目CPU·预留IOPS保留连接没有外部约束

结构图,而不是测量结果:迄今为止,还没有发布这两种拓扑的比较性能数据。

连接预算通常是生产中最明显的症状,甚至在延迟之前也是如此。这是我们的 max_connections 调整指南 和我们的 比较 PgBouncer、Supavisor 和 PgCat的详细主题。

A transaction mode pooler (PgBouncer, Supavisor, PgCat) mitigates connection exhaustion, but does not remove CPU or IOPS contention: it reuses existing server connections, it does not add additional CPU cores or disk throughput to the cluster. Our article on transaction pooling mode details what this mode actually changes, and what it doesn't change.

#
极限

RLS 隔离数据,而不是资源

行级安全性解决了另一个问题:它防止查询在逻辑级别读取或修改另一个租户的行。它不为特定租户保留 CPU 周期、连接插槽、磁盘吞吐量。

两个租户可以拥有完全无懈可击的 RLS 策略,但同时会互相贬低:吵闹的邻居是物理资源的问题,而不是访问权限的问题。一旦 EPIRB 到位,混淆两者会导致操作安全的错误感觉。

信息

对于逻辑隔离(RLS 策略、 service_role、安全方面项目之间的边界),请参阅我们的专门文章: RLS 和每个项目的专用基础、Aurabase 的多租户隔离选择。本文仍然停留在物理资源层面。

#
在代码中

Aurabase 模型,已在代码中验证

配置程序代码 (aura-provisioner) 准确记录了活动 Postgres 项目的两种可能的架构,来自代码称为任务 12 的配置整合: FullyDedicated 和 SharedClusterDedicated。旧的架构粒度模型已从配置路径中删除。

enterprise 级别触发 FullyDedicated:整个 CNPG 集群,为该单个项目保留。所有其他级别(免费、专业、团队)都会路由到 SharedClusterDedicated:项目组织的 CNPG 集群上的成熟 Postgres project_<uuid> 数据库。因此,它不是一个共享模式:即使在标准计划中,您的数据库也是一个完整的 Postgres 数据库,而不是公共表中的一行。共享的是集群(CPU、RAM、磁盘、连接),而不是基础本身。

组织的 CNPG 集群是在配置其第一个 Postgres 项目时创建的,并且从不托管来自其他组织的项目,这是在代码级别锁定的设计选择(org_cluster.rs,创建时组织的 Postgres 咨询锁定)。因此,共享 Aurabase 平台上唯一可能吵闹的邻居是您自己组织的另一个项目,而不是第三方客户的项目。

fleet.rsrust
/// 组织集群的名义容量(项目基地数量)。
/// 可观察性阈值:超过此阈值,引导组织走向完全专用。
/// 可通过 FLEET_CLUSTER_CAPACITY 控制(默认 1000,有限 [1, 1_000_000])。
pub fn fleet_cluster_capacity() -> i32 {
    std::env::var("FLEET_CLUSTER_CAPACITY")
        .ok()
        .and_then(|v| v.parse::<i32>().ok())
        .filter(|n| (1..=1_000_000).contains(n))
        .unwrap_or(1000)
}
2
可能的架构
FulledDedicated 或 SharedClusterDedicated,没有其他
1000
基地/簇(默认)
可配置,限制在 1 到 1,000,000 之间
PG 16
Postgres 版本
租户/车队集群尚未达到 PG 17

Aurabase 管理的 PostgreSQL 集群架构规范。

每个集群 1000 个碱基的阈值并不是硬性限制:它是一个可观察性基准,会触发迁移到 FullyDedicated的建议,而不是自动阻止。它不再驱动任何放置决策,每个组织现在只能使用一个集群。

每个集群,无论是专用集群还是集群集群,都公开一个 CNPG Pooler (PgBouncer),它可以吸收两种拓扑中活动连接的部分压力。下面详细介绍了该池程序针对资源争用实际所做的更改。

共享集群的 CPU/RAM 大小在组织之间也不一致:它通过专用函数(FleetSizing::from_org_plan,在 org_cluster.rs中验证)从组织级别派生,而不是从应用于所有级别的单一大小派生。团队级别的组织不会采用与自由级别的组织相同的方式调整集群大小。

这两种架构在 PostgreSQL 16 上运行,而不是版本 17,在生产中使用的 CNPG 镜像的 Dockerfile 中进行了验证。这种版本选择有其自身的调整含义,详细信息请参见我们的 Postgres 16 vs 17 vs 18 比较。

#
决定

当池化就足够了,当需要专用时

阿斯图塞

池化并不是一种廉价的妥协。它对应于绝大多数正在开发、启动或适度增长的项目的流量,在这些项目中,专用集群将是额外的成本,而没有可衡量的效益。

信号共享就够了专用推荐
正式遵守物理隔离规定(卫生、人力资源、公共部门)否是的
可预测的交通流量,适度的高峰是的
不可预测且持续的峰值负载限制的风险是的
预算紧张,产品处于验证阶段是的
要求记录绝缘的合同条款 (DPA)否是的

对于受记录物理绝缘合同义务约束的项目,我们的 DPA 和 合规性 页面详细介绍了每个级别涵盖的内容。

Bytebase 等多个模式迁移管理工具强调了逐个租户模型的缺点,该缺点是操作性的而不是技术性的:每个迁移都必须在每个基础上逐一应用和验证,即使它们共存于同一集群上也是如此。完全专用的集群并不能消除这一成本,甚至还增加了这一成本:每个集群进行一次迁移来独立监控,而不仅仅是一次。

专门研究多租户软件架构的资源(例如 CodeOpinion)定期将这种中间方法(基于共享基础设施的每个租户)呈现为共享方案和完全专用集群之间的合理折衷,而不是两个极端之间的二元选择。

从共享到专用不需要重写模式或更改引擎:在这两种情况下,它都是 Postgres,具有与我们的 Supabase 到 Aurabase 迁移指南中描述的相同的 pg_dump / pg_restore 链。更改级别仍然是切换操作,而不是应用程序重写。

#
常见问题解答

常见问题

Aurabase 共享数据库是否会因其他公司的项目而减慢速度?+
不会。Aurabase 共享 CNPG 集群属于单个组织,并且从不托管来自第三方组织的项目,并在配置程序代码 (org_cluster.rs) 中进行验证。这一层唯一可能吵闹的邻居是您自己组织的另一个项目。
Aurabase 的共享层是否使用带有tenant_id 列的共享架构?+
不会。每个项目都会收到自己的 Postgres 数据库 (<9>project_<uuid></9>),即使是免费、专业和团队级别也是如此。共享的是 CNPG 集群(CPU、RAM、磁盘、连接),而不是基础本身或其图表。
我如何知道我的项目是否需要专用集群?+
最常出现的三个信号是:对资源物理隔离的正式合规性要求、定期使可用连接饱和的持续且不可预测的流量,或者需要记录隔离的 DPA 类型合同条款。在大多数情况下,低于这些阈值,统筹在经济上仍然更加合理。
每个簇 1000 个碱基的阈值是硬性限制吗?+
不,这是一个可观察性阈值,而不是自动技术障碍。它可以通过变量 FLEET_CLUSTER_CAPACITY (默认 1000,限制在 1 到 1,000,000 之间)进行配置,并用于表明组织应该面向专用集群。
EPIRB 足以防止邻居吵闹吗?+
不会。RLS 会过滤查询可见的行;它既不保留 CPU,也不保留 IOPS,也不保留与特定租户的连接。如果两个具有完全无懈可击的 RLS 策略的租户共享同一个物理集群,它们仍然可能会互相降低性能。请参阅我们关于 RLS 和每个项目的专用基础的文章,了解逻辑隔离部分。
为什么池化成本低于专用集群?+
因为 Postgres 集群的固定成本(CPU、RAM、预留存储、备份)分布在占用该集群的组织的所有基础上,而不是由单个项目全额支付。即使实际项目负载较低,专用集群仍然需要付费,这使得它成为一个合理的选择,尤其是在合规性或流量信号证明其合理性的情况下,而不是之前。
#
结论

要记住什么

专用库和共享库在数据安全上并不冲突:两种模型都可以在逻辑层面上正确地将一个租户与另一个租户隔离。它们在物理资源(CPU、IOPS、连接、缓存、维护窗口)上相互对立。正是这个计划定义了一个吵闹的邻居,而不是一个写得不好的 RLS 策略。

在配置程序代码中验证的 Aurabase 模型默认保留中间折衷方案:每个项目一个专用的 Postgres 数据库,位于共享集群上,但严格为单个组织保留,并为业务级别保留完全专用的集群。正确的选择取决于您的实际限制,而不是反射,专用始终是最佳选择。

准备好部署了吗?

五分钟内完成您的后端。

无需信用卡 · 500 MB 免费 · 50,000 MAU