PostgreSQL 18 Serverless 实战:弹性扩容、冷启动与成本优化

📅 发布时间:2026/10/13 20:30:33
PostgreSQL 18 Serverless 实战:弹性扩容、冷启动与成本优化
作为一个常年和数据库打交道的人其实我很少会对某个新特性特别兴奋但 PostgreSQL 的 Serverless 能力确实是个例外。尤其是在 PostgreSQL 18 这个版本周期里Serverless PostgreSQL 已经不再是云厂商各自为战的“半残”功能而是变成了一个真正可以认真考虑投入生产环境的架构选项。这篇内容是“PostgreSQL 18 从新手到大师”系列里的第 2.5 节专门来聊 Serverless PostgreSQL。我会把之前给团队做技术选型和实操落地时踩过的坑、验证过的配置、以及我认为值得注意的细节都整理出来。如果你正在纠结要不要上 Serverless或者被冷启动、连接数、成本预估这些问题搞得头疼这篇应该能帮你省点时间。1. 为什么 PostgreSQL 18 值得认真考虑 Serverless 模式1.1 从“自建数据库”到“按量付费”的思维转变先从一个特别常见的场景说起。我之前所在的公司早期所有测试环境和部分生产分析任务都跑在自建的 PostgreSQL 上。机器规格是预先买好的比如 8核32G 的虚拟机日常 CPU 使用率可能只有 5%但为了应付偶尔的报表查询高峰这堆机器还得一直开着。每年的机器成本、运维成本、备份空间成本算下来是一笔不小的开销而且大部分时间资源都在闲置。Serverless PostgreSQL 的出现改变了这个资源模型。它不再是给你一台固定的数据库服务器而是给你一个可以动态伸缩的数据库服务。你不需要关心底层有多少台机器也不需要预估未来半年要买多大规格的机器只需要告诉数据库“我的工作负载大概在什么范围”剩下的由数据库自动处理。举个最直观的例子一个典型的数据分析应用白天上班时间查询量很大晚上和周末几乎没人用。用传统方式你要为白天的峰值去购买一整台机器晚上那十几个小时机器就空转。而 Serverless 模式可以在夜间自动把计算资源缩减到接近零只保留存储和必要的元数据成本直接下降一大截。在 PostgreSQL 18 这个版本里Serverless 模式的一个核心变化是对自动暂停和恢复机制做了更细粒度的控制。之前版本的暂停恢复有点像开关要么全速跑要么完全停。18 版本引入了一些更灵活的参数和更平滑的伸缩策略这让它更适合承载那种“间歇性高负载”的业务。1.2 PostgreSQL 18 到底给 Serverless 带来了什么严格来说PostgreSQL 18 本身是一个数据库内核版本而 Serverless 更多是云厂商基于它构建的一种服务形态。但内核版本和 Serverless 能力是强相关的。18 版本在某些关键能力上的增强直接让 Serverless 架构变得更实用了。首先是资源扩展的粒度。旧方案里你可能只能选择 2核4G、4核8G 这样的固定套餐扩展要重启实例甚至要迁移数据。在 PostgreSQL 18 的 Serverless 实现里计算资源可以在一个最小值和最大值之间动态调整比如从 0.25 vCPU 平滑升到 4 vCPU整个过程不需要重启也不需要修改应用连接字符串。其次是存储与计算的分离架构更成熟了。Serverless 数据库的核心是计算节点不保存数据数据都放在共享存储层上。PostgreSQL 18 对共享存储场景下的缓存管理、锁管理、事务提交流程都做了针对性优化减少了因为频繁切换计算节点带来的数据一致性问题。我实测下来在弹性扩容过程中事务中断的情况比版本 14、15 时代要少很多。另外18 版本对监控和统计信息的收集也有改进。对于 Serverless 来说监控特别重要因为你不知道数据库什么时候会自动扩容、什么时候会触发暂停。更精细的统计信息能帮助你判断当前的伸缩行为是否合理也能帮助云厂商层面更好地调度资源。1.3 什么样的情况才真正需要 Serverless很多人一听 Serverless 就觉得“所有场景都应该用”这是个误区。我见过一些团队把核心交易数据库也强行放到 Serverless 上然后被冷启动延迟搞得痛不欲生。根据我的观察以下这几类情况更适合用 Serverless PostgreSQL开发测试环境开发环境的数据库负载很低但需要 24 小时在线。用 Serverless 模式空闲时自动暂停开发人员需要连库时自动唤醒成本能做到极低。间歇性或周期性负载比如运营后台的报表系统每天早上和下午各有一个查询高峰其他时间基本空闲。Serverless 可以在高峰时自动扩展闲时缩容成本优化效果明显。新项目或初创项目业务量不确定不好预估数据库规格。用 Serverless 可以先跑起来等业务量上来了再调整配置避免前期过度投入。多租户隔离场景每个租户或每个项目组需要独立的数据库实例但每个实例的负载都不高。用 Serverless 可以按需创建多个小型实例资源隔离和成本分摊都更容易。反过来如果你是长期高并发、对延迟极其敏感的 OLTP 业务或者有大量长事务和复杂 JOIN 的分析型业务可能还是用保活模式或独立部署更合适。Serverless 的弹性是有代价的后面我会详细讲这个代价在哪里。2. 核心机制拆解暂停、恢复、弹性扩容与计费逻辑2.1 自动暂停与冷启动到底是怎么运作的理解 Serverless PostgreSQL第一关就是搞懂“暂停”和“恢复”是怎么回事。简单打个比方传统数据库是一台一直通电的冰箱不管里面放没放东西电费都在走。Serverless 数据库更像一个带感应功能的智能插座你不在家时自动断电你一回家插上设备它就通电。在 PostgreSQL 18 的 Serverless 实现里暂停机制大致是这样工作的数据库会监控一段时间内的活动连接数和 CPU 使用率。如果发现持续一段时间比如 5 分钟没有活跃的连接或查询它会触发一个“空闲检查”。确认没有活动事务后计算节点会进入“冻结”状态把内存中的状态收尾写盘然后释放计算资源。此时数据库仍然存在数据和表结构都在但不再占用 CPU 和内存。当新的连接请求到来时系统检测到没有运行中的计算节点会立刻申请资源并启动一个新的计算节点把共享存储上的数据加载到内存然后接受连接。这个从“收到连接请求”到“数据库响应查询”的过程就是所谓的“冷启动”。冷启动的时间通常在几秒到十几秒之间具体取决于数据量、缓存命中率和底层资源调度速度。这里有个关键心得冷启动时间对短连接的影响很大。如果你的应用是“每个请求都新建数据库连接”那么每次连接都可能触发一次冷启动用户体验会非常糟糕。我的建议是应用侧一定要使用连接池并且保持至少一个保活连接。2.2 弹性扩容的粒度CPU、内存和连接数弹性扩容不是无限扩它有一个范围。以某云厂商的 Serverless PostgreSQL 为例这是我实际用过的配置其他厂商逻辑类似最小计算规格可能是 0.25 vCPU 和 1GB 内存最大可以到 32 vCPU 和 128GB 内存。这个范围可以随时调整不需要重启数据库。扩容的触发条件通常是 CPU 利用率或内存使用率超过一个阈值比如连续 30 秒超过 70%系统就会在下一轮调度周期中分配更多的资源。缩容则相反当负载降下来后系统会逐步释放多余资源。这里有一个容易踩的坑连接数限制和计算规格是绑定的。小规格实例允许的最大连接数很低可能只有 100 左右。如果你的应用池化连接数超过了这个限制即使 CPU 和内存看起来很充足也会报 “too many connections” 错误。解决方法是在 Serverless 配置里预留足够大的最小规格或者为应用设置更合理的连接池上限。我比较推荐的做法是应用侧使用连接池中间件比如基于 PgBouncer 的思路把前端连接和后端数据库连接解耦。前端连接可以很多后端真正打到数据库的并发连接保持在一个低水位这样既能享受 Serverless 的弹性又不会被连接数限制卡脖子。2.3 存储与计算分离带来的安全隐患和应对Serverless 架构下数据不是存在计算节点本地磁盘上的而是在一个独立的共享存储层。这意味着计算节点可以随时销毁、随时新建但数据始终在那里不会丢失。这种架构天然支持“计算零存储”模式也让弹性扩容成为可能。但存储与计算分离也带来了一些需要注意的地方。首先是网络延迟。计算节点访问共享存储的网络开销比本地磁盘要大一截所以 Serverless 实例的延迟通常比专用实例高一些。对于大部分业务延迟需求在 50ms 以内来说问题不大但如果你的业务需要个位数毫秒级的延迟Serverless 可能不适合你。其次是数据安全。因为存储层是独立的你需要确认云厂商的存储层是否加密、备份策略是否完善、跨区域容灾是否可用。我个人的经验是一定要开启自动备份并且定期做恢复演练。不要因为云厂商说“数据有冗余”就天真地以为万事大吉。另外既然计算节点可以随时重建内存中的数据在节点释放时必然丢失。PostgreSQL 自身有 WAL 机制保证持久化但那些停留在内存中的临时表、未刷盘的 dirty page 会消失。如果你有依赖临时表的业务逻辑需要注意这类数据是不可靠的。2.4 计费逻辑与成本模型千万别被低起步价迷惑Serverless 的计费模型通常由三部分组成计算资源费用、存储资源费用、备份和流量费用。计算资源是按实际使用量计费的单位是 vCPU 和内存的累加值通常以“秒”为单位。也就是说数据库运行了 10 分钟就收 10 分钟的钱暂停了就不收计算费。这个机制很诱人但要注意这里有“最低计费门槛”和“操作次数费”的概念。有些云厂商会设一个最低运行时长比如每次恢复后至少计费 1 分钟或者当弹性扩容发生时会按照新的规格重新计费。存储费用通常按实际占用的空间计费按月结算。这个费用相对固定不太受负载波动影响。备份费用是按备份集大小和保留时长计算的一般建议设置一个合理的保留周期比如 7 天避免备份空间无限增长。我画了一张简化对比表列出传统自建和 Serverless 的成本结构差异方便你有个直观感受成本项传统自建数据库Serverless PostgreSQL计算资源固定购买空闲也付费按需使用暂停不付费存储资源按磁盘大小预购按实际用量付费备份存储通常自己管理按备份集大小计费运维人力高补丁、扩容、监控低云厂商托管扩容成本需要停机或迁移自动弹性无需操作我在一个模拟项目中做过测算。一个日均查询量 2 万次、存储 50GB 的运营报表系统用 4核16G 自建实例月成本约 1500 元换成 Serverless 后避开高峰时段自动暂停月成本降到 400 元左右。当然这是一个比较理想的场景如果你的负载是均匀持续的Serverless 的单价其实并不比传统模式便宜太多。核心在于Serverless 省的是“闲置资源”的钱不是“使用资源”的钱。3. 从零搭建一个 Serverless PostgreSQL 实例完整实操记录3.1 创建实例前的规划这些参数决定了后续体验我在第一次创建 Serverless 实例时因为对参数理解不足把最小计算规格设得太低结果频繁触发冷启动后来不得不反复调整。这里分享一套我认为比较合理的创建流程以某云厂商的控制台为例其他平台大同小异第一步选择数据库引擎版本务必选 PostgreSQL 18或厂商支持的最新 18.x。版本越新对 Serverless 的优化越好。第二步配置计算规格范围。这可能是整个创建过程中最重要的参数。我的建议是最小规格不要低于 0.5 vCPU / 1GB 内存最大规格根据你的真实负载峰值来定。如果你不确定峰值可以先设置一个较大的上限运行一段时间后再根据监控数据调低。最小规格设置过低冷启动频率会变高设置过高闲时成本又降不下来。第三步设置自动暂停策略。通常有两个参数空闲多少分钟触发暂停一般是 5-10 分钟以及是否允许自动暂停。对于生产环境我建议把自动暂停设置得保守一点比如 30 分钟或者干脆关闭自动暂停。因为冷启动虽然时间不长但对于线上服务来说每一次冷启动都可能造成请求超时。第四步存储空间和区域。存储空间建议设置一个合理的上限比如 100GB并且开启自动扩容。区域选择尽量靠近你的应用部署区域减少网络延迟。第五步网络访问方式。Serverless 实例通常支持内网访问和公网访问。生产环境一定要走内网VPC公网只用于开发调试而且必须配置白名单限制来源 IP。3.2 连接方式与连接池配置别让冷启动毁了体验创建完成之后你会得到一个连接地址看起来和普通 PostgreSQL 差不多比如xxx.pgserverless.example.com和端口5432。连接方式也和标准 PostgreSQL 完全一致你可以用任何兼容 PostgreSQL 的客户端psql、DBeaver、pgAdmin 等连接。重点在于你的应用侧连接策略。我强烈建议在所有访问 Serverless PostgreSQL 的应用中使用连接池组件。下面是一个基于应用层的连接池配置示例Java 的 HikariCP你可以参考这个思路HikariConfig config new HikariConfig(); config.setJdbcUrl(jdbc:postgresql://xxx.pgserverless.example.com:5432/mydb); config.setUsername(myuser); config.setPassword(mypassword); config.setMaximumPoolSize(20); config.setMinimumIdle(5); config.setIdleTimeout(60000); config.setConnectionTimeout(30000); config.setKeepaliveTime(30000);这里有两个关键配置minimumIdle和keepaliveTime。minimumIdle设置连接池中至少保留的空闲连接数可以避免频繁建立新连接触发冷启动。keepaliveTime会让连接池定期发送心跳包从而让数据库保持“有人用”的状态减少意外的暂停发生。但我必须提醒你连接池只能解决连接复用的问题无法完全消除冷启动。如果你在无人访问的深夜第一次发出请求数据库必然要从暂停状态恢复。这种场景我一般建议配合一个“预热”机制在业务低峰过后定时执行一个极轻量的查询比如SELECT 1把数据库提前唤醒。3.3 数据迁移把原有 PostgreSQL 数据迁到 Serverless如果你手上已经有一个传统 PostgreSQL 实例需要迁到 Serverless 架构其实比想象中简单。PostgreSQL 生态里迁移工具很成熟最常用的是pg_dump和pg_restore。我推荐一个低风险的迁移流程。先从旧库导出结构再从新库导入结构然后导数据最后切换应用连接。导出导出逻辑示例# 1. 导出结构不含数据 pg_dump -h 旧库地址 -U 旧库用户 -d 旧库名 --schema-only -f schema.sql # 2. 导出新库应用结构 psql -h 新库地址 -U 新库用户 -d 新库名 -f schema.sql # 3. 导出数据使用自定义格式方便并行恢复 pg_dump -h 旧库地址 -U 旧库用户 -d 旧库名 -Fc -f data.dump # 4. 在新库并行恢复数据 pg_restore -h 新库地址 -U 新库用户 -d 新库名 --jobs4 data.dump整个过程有几个注意点。迁移旧库之前最好先中断写入操作确保数据一致性。如果没法中断写入可以先用pg_dump做一次全量备份然后开启逻辑复制logical replication做增量同步等追上进度后再切换。用逻辑复制的好处是切换瞬间几乎无感知。迁移完成后我的习惯是保留旧库运行一个观察周期比如一周期间跑一些关键业务查询对比新旧库的响应时间、连接稳定性确认没问题后再销毁旧库。这个做法多花了一点存储钱但能换来回退的安全感。3.4 应用侧改造重试机制与超时设置Serverless PostgreSQL 和传统数据库的一个显著差异是它可能出现“暂时不可用”的状态——比如在冷启动期间或者自动扩容切换计算节点瞬间连接可能会超时或中断。这不是数据库故障而是架构特性。但应用侧必须为这种特性做好准备。我的建议是在业务代码里增加数据库操作的重试机制特别是连接建立阶段和幂等查询阶段。举个例子一个简单的查询请求如果第一次因为冷启动超时理论上等一秒后重试第二次就能正常返回。第一个实操建议是设置合理的连接超时时间。默认的 30 秒太长会让用户感受不到系统错误我一般设置在 5 秒以内这样重试机制才能及时触发。第二个建议是在数据库访问层增加退避策略。重试不要立刻执行而是采用递增的延迟比如第一次等 500ms第二次等 1 秒第三次等 2 秒最多重试三次。这样可以避免在冷启动期间多个请求同时涌入把刚刚恢复的数据库又打垮。第三个建议是考虑使用读写分离。把高频的读操作部署在只读节点上写操作集中在主节点。Serverless 模式下只读节点也可以独立扩缩容这能让你的系统在高峰时读能力充足闲时又能把只读节点暂停掉进一步优化成本。4. 真正生产环境里踩过的坑常见问题与排查实录4.1 冷启动延迟高居不下怎么优化冷启动是 Serverless PostgreSQL 绕不开的话题但不同场景下冷启动的延迟差异很大。有一次我在一个项目里发现查询响应时间经常从几十毫秒突然跳到 6-8 秒一查全是冷启动造成的。排查思路是这样的。第一观察数据库监控指标看是不是频繁触发“恢复”事件。第二检查连接池配置确认最小连接数是否设得太低。第三看看业务访问模式是否存在明显的“空闲窗口”导致数据库进入暂停状态。我的优化方案有三个调整自动暂停策略。把空闲触发暂停的时间从 5 分钟调长到 60 分钟甚至关闭自动暂停。代价是数据库会一直保持运行状态计算费用会增加但换来的是响应时间稳定。使用预热任务。如果业务确实有固定的空闲时段可以写一个定时任务在空闲时段结束后先发一个SELECT 1让数据库恢复。这个任务本身消耗极低但能把冷启动延迟挡在用户请求之外。调大最小计算规格。冷启动慢的一个原因是规格太小内存不足导致数据加载时间变长。把最小规格从 0.25 vCPU 提高到 1 vCPU冷启动时间通常能缩短一半以上。4.2 连接数限制的困扰too many connections这个错误我几乎每次用 Serverless 都会遇到好几次都让我误以为是应用代码出问题了。在 Serverless 模式下连接数限制往往比传统实例要小因为每个连接都会占用内存而弹性扩容时内存是逐步增加的系统必须设一个安全上限。比如最小规格 0.5 vCPU / 1GB最大连接数大约在 200 左右。如果你的应用并发量稍大很容易就撞上这个上限。最直接的办法是调整连接池的maximumPoolSize。前面提到 HikariCP 示例里我设置了 20这个值看起来很小但对于大多数业务系统来说完全够用。请大家理解一个概念数据库连接是稀缺资源但应用并发量不等于数据库并发量。你的应用可能有 1000 个请求同时在处理但它们真正同时执行 SQL 的只有很少一部分。通过连接池限流把并发打满数据库连接限制的概率降到最低。如果连接池调优后还是不够那就得考虑提升最小计算规格了。记住连接数和计算规格是绑定的你需要一个更大的“底座”。4.3 数据安全与备份恢复容易忽略的细节Serverless 的存储层通常有多个副本但多副本不等于有备份。我见过一个项目因为业务误操作导致表数据被删结果发现自动备份周期是 24 小时而且是凌晨两点执行的中午的误删操作根本找不到可还原的时间点。所以我的建议是在创建 Serverless 实例时把自动备份周期设置为 6 小时甚至更短并开启实时 WAL 归档。这样即使误操作也能通过 PITR时间点恢复把数据恢复到误操作前的几秒钟。另外备份空间是独立计费的而且增长很快。要设置合理的备份保留时长比如保留 7 天超出部分自动清理。我见过有些项目因为忘记设置保留策略备份空间比主存储还大月账单直接爆掉。4.4 监控与成本预警Serverless 必须盯紧的指标Serverless 的计费是动态的这也意味着成本是可变的。如果你不盯紧监控月底账单可能会超出预期两倍甚至更多。我自己管理 Serverless 实例时会配置三类监控指标告警计算资源使用率包括 CPU、内存、活跃连接数。这能帮你判断弹性扩容是否正常。弹性事件包括扩容、缩容、暂停、恢复事件的记录。频繁的弹性事件通常意味着配置不合理需要调参。费用趋势按日、按周查看计算费用变化一旦发现异常增长立刻检查是哪些时段在消耗资源。监控告警的配置方式以某云厂商为例可以这样设置在控制台找到监控报警页面新增一个告警规则指标选择“CPU 利用率”阈值设为 80%持续时间 5 分钟通知方式选择短信和邮件。这样当数据库持续高负载时你能第一时间收到通知而不是月底看账单时才后悔。实际上我后来做了一个更极致的成本控制策略将非核心项目比如个人演示站、临时测试环境的 Serverless 最大计算规格设得很低比如 0.5 vCPU / 1GB并且开启自动暂停。这样即使有人恶意刷接口费用也极其有限每月稳稳控制在几十元以内。5. 我的最终体会与选型建议说了这么多理论、实操和踩坑记录最后分享一下我自己总结的选型判断方法。我的做法是任何新的数据存储需求第一反应先跑一个“Serverless 适配性打分”负载是否间歇性是则 1延迟要求是否低于 50ms高则 -1是否有长期连接的写入型业务有则 -1是否需要频繁的数据库版本升级或配置调整是则 1团队是否有专职 DBA有则 -1预算是否敏感且业务增速不确定是则 1总分高于 2 分我会优先考虑 Serverless总分低于 0 分直接选传统集群或自建。这个方法不一定适用于所有团队但它帮助我在多次选型中避免了想当然的决策。还有一个不得不提的经验如果你所在团队对 PostgreSQL 的运维能力很弱即使负载是均匀持续的我也建议至少把测试环境和开发环境放到 Serverless 上。它减少了大量机械性的环境维护工作让工程师把精力放在业务本身。生产环境可以逐步试点不一定非要第一天就全量迁移。PostgreSQL 18 的 Serverless 模式对于中小团队、分析型负载、间歇性业务来说确实提供了一个非常省心的新选择。但请务必记住Serverless 不是“数据库”概念的革命而是“资源交付方式”的变革。它解决的是成本和运维问题并不会自动让你的数据库变快也不会消除你对数据模型、索引设计、SQL 质量的责任。如果你正打算尝试建议从一个小项目开始开一个 0.5 vCPU 最小规格的实例部署一个现有的业务运行两周把监控和成本数据拉出来看看。它会很直观地告诉你这种新架构适不适合你的场景。