数据库圈有个反常识的共识正在形成:最快的存储和最便宜的存储, Postgres(一种开源关系型数据库)想要同时用上,而且让两者无缝协作。

这不是降本增效的妥协,而是一次架构层面的重新设计——把NVMe(非易失性内存主机控制器接口规范,一种高速存储协议)推到热路径,让S3(简单存储服务,一种对象存储)接管一切 else。

打开网易新闻 查看精彩图片

为什么分层突然变得紧迫

Postgres的存储架构正在经历代际压力。传统上,它依赖本地磁盘做所有事:事务日志、表数据、索引、临时文件。但当数据量突破TB级,这种"一锅炖"模式开始崩解。

云原生场景下,存储成本曲线变得陡峭。NVMe SSD(固态硬盘)每GB成本是S3的40-50倍,但延迟差距是1000倍量级(微秒 vs 毫秒)。

关键洞察:工作负载从来不是均匀分布的。80%的查询可能只触及5%的数据——这是经典的帕累托分布。

Postgres社区和周边生态(包括Neon、Aurora等衍生方案)正在押注一个策略:用NVMe兜住热数据,用S3吞下冷数据,中间用智能分层逻辑粘合。

NVMe在热路径的具体角色

热路径(hot path)指查询必须直接命中的数据通道,延迟敏感到极致。

Postgres把这几类数据钉在NVMe上:

写入缓冲层(Write-Ahead Log,预写日志):事务提交必须同步落盘,NVMe的亚毫秒延迟直接决定吞吐量上限

活跃表和索引的缓存页:Buffer Pool(缓冲池)的扩展,但溢出到本地NVMe而非直接写S3

临时排序和哈希表:复杂查询的中间状态,随机IO(输入输出)密集

Neon的架构文档里有个细节:他们把Postgres计算节点设计成无状态的,但本地仍挂载NVMe作为"第二层缓存"——不是替代S3,而是作为S3的前置加速器。

这层设计的微妙之处在于:NVMe在这里不是持久化主存,而是延迟优化的缓冲带。数据最终归宿仍是S3,但NVMe承担了"削峰填谷"的流量整形角色。

S3如何接管"一切 else"

S3的价值不只是便宜,而是解耦

当Postgres把表数据、历史快照、归档日志、甚至只读副本的基线数据全部塞进S3,几个连锁反应发生:

• 计算节点可以真正无状态,秒级扩缩容

• 存储成本与计算成本脱钩,按需分层计价

• 跨区域复制变成S3的内置能力,无需Postgres自己折腾流复制

Aurora PostgreSQL(亚马逊的关系型数据库服务)是最早验证这条路的。他们的存储层自研,但逻辑一致:日志即数据库,S3兼容对象存储作为真实数据源,本地SSD只是缓存。

开源侧,pg_backrest和wal-g这类备份工具早已把S3作为默认目标。现在趋势是更进一步:让S3不只是"备份目的地",而是"活跃存储层"的一部分。

Neon的分页层(Page Server)设计典型:热页在NVMe,冷页按需从S3拉取,后台异步刷回。查询冷数据时首次访问有毫秒级惩罚,但后续缓存命中后回到微秒级。

分层架构的五个工程要点

这条技术路线能走通,依赖几个关键设计决策:

1. 页级粒度 vs 文件级粒度

Postgres传统以8KB页为IO单位。分层存储必须保持这个粒度,否则随机访问模式会拖垮性能。Neon的Page Server直接操作页,而非整个表文件。

2. 一致性模型的妥协

S3的强一致性是2019年后才保证的,且延迟高于本地存储。Postgres的WAL机制需要调整:本地NVMe负责"已提交即持久",S3负责"最终一致的大规模存储"。

3. 预取与缓存淘汰策略

冷数据首次访问的惩罚必须被掩盖。常用手段:基于查询计划的顺序预取、LRU-K(最近最少使用改进算法)变体的缓存管理、以及工作负载驱动的热数据预测。

4. 写入路径的双写问题

数据既要进NVMe(低延迟响应客户端),又要异步刷S3(持久化)。这引入窗口期的丢失风险。主流方案:WAL同步写NVMe,后台批量上传S3,崩溃后从WAL重放。

5. 成本核算的透明度

用户需要知道每笔查询的存储成本构成。Neon的定价模型区分"计算单元"和"存储单元",后者再细分活跃存储(NVMe层计费)和归档存储(S3层计费)。

谁在这条路上走得最远

目前有三类玩家验证不同变体:

Neon:完全重构存储层,计算与存储彻底分离,开源且云中立

Aurora PostgreSQL:深度集成AWS生态,存储层闭源但API兼容

Crunchy Bridge / StackGres:托管Postgres,分层策略较保守,主要用S3做备份和归档

Neon的技术博客披露过一个数字:他们的冷启动时间(计算节点从零到服务查询)可以压到秒级,因为数据不在本地,而在S3按需拉取。代价是首次查询延迟,但这对很多Web应用可接受。

Aurora则走另一条路:存储层自研,但向上暴露标准Postgres协议。他们的卖点是"无需改代码",但锁定在AWS。

对开发者的实际影响

如果你在用Postgres,这条趋势线意味着几件事:

• 选型时关注存储架构:是真正的分层设计,还是只是"本地盘+定期备份"

• 查询模式决定成本:随机访问冷数据会触发S3拉取,账单可能意外膨胀

• 扩展性假设改变:计算节点可以很小、很多、很 ephemeral(短暂存在的),因为状态在S3

• 调试复杂度上升:性能问题可能出在NVMe缓存未命中、S3延迟、或预取策略失效,需要新的可观测工具

一个具体建议:如果你的工作负载有明显的时间局部性(最近数据被频繁访问),分层架构的性价比极高。反之,如果访问完全随机且均匀,NVMe缓存的命中率会崩盘,不如直接用全闪存。

Postgres的存储分层不是万能药,但它把"成本-性能"的权衡从硬件采购层面,下沉到了运行时的自动调度层面。这符合云原生的大方向:让基础设施替你操心容量规划,你只关心查询本身。

当NVMe和S3的边界被软件定义,Postgres正在变成某种"存储编排器"——它不再假设自己拥有完整的磁盘,而是动态地在速度层和容量层之间搬运数据。这种架构转变,会不会最终模糊"数据库"和"数据湖"的界限?