
一次系统优化中,我关闭了一整套 Redis 集群。没有告警,没有波动,监控延迟曲线在轻微晃动后,反而下降了。这一刻让我意识到,Postgres 18 的性能表现,在某些场景下足以超越我们精心维护的缓存层。
本文将分享这一决策背后的技术细节、Postgres 18 带来的关键变革,以及如何在评估后安全地简化架构。
缓存层成为瓶颈的教训
在过去多年的架构中,我们遵循一个经典模式:应用先查询 Redis,若未命中再查询 PostgreSQL 数据库,并将结果回写到 Redis。我们优化了 TTL 和驱逐策略,自认为架构非常“专业”。
然而,在一次流量高峰中,Redis 集群出现了问题:CPU 使用率达到 90%,网络带宽吃紧,延迟剧烈波动。但与此同时,底层的 PostgreSQL 数据库却非常空闲。这次事件迫使我们反思:投入大量资源维护的缓存层,是否反而成为了系统的瓶颈?
Postgres 18 的性能飞跃
Postgres 18 带来了若干核心改进,正是这些改进让我们重新思考“数据库必须被缓存保护”这条铁律。作为现代应用架构中的核心数据库/中间件,其性能提升直接影响技术选型。
核心升级包括:
- 全新的异步 I/O 子系统:能够自动批量合并多个读取请求,使得顺序扫描和位图堆扫描的速度最高可提升 3 倍。
- 更智能的索引使用:优化器在多列索引场景下(如跳跃扫描 Skip Scan)的选择更加精准,能更好地遵循开发者的设计意图。
- 虚拟生成列:允许将计算派生出的字段直接定义在表中,简化了查询逻辑,减少了对应用程序层计算或缓存填充的依赖。
这些能力的结合,催生了一个大胆的想法:如果数据库自身已经足够快,我们是否还需要独立的缓存层?
一次改变架构观的实验
我们没有贸然行动,而是进行了“暗流量测试”。我们选取了一个典型的、缓存受益显著的查询场景:用户仪表盘数据聚合。
首先,在 Postgres 18 上对相关查询进行优化。我们创建了更有效的多列索引,并利用优化器改进来确保执行计划最优。
CREATE INDEX CONCURRENTLY idx_orders_customer_status_date
ON orders(customer_id, status, created_at DESC);
-- 简化的仪表盘查询
SELECT o.id,
o.total_amount,
o.status,
o.created_at
FROM orders o
WHERE o.customer_id = $1
AND o.status IN ('PAID', 'SHIPPED')
ORDER BY o.created_at DESC
LIMIT 20;
随后,在测试环境中启用异步 I/O,并将一部分生产流量绕过 Redis,直接导向 Postgres 18 数据库。
压测配置:
- 1000 并发用户
- 读写比例 90:10
- 数据规模:1500万订单,200万用户
测试结果对比如下:
| 架构模式 |
P95 延迟 |
缓存命中率 |
备注 |
| Redis + Postgres |
72 ms |
91% |
偶发缓存风暴 |
| 仅 Postgres 18 |
54 ms |
100% |
无外部缓存 |
结果令人惊讶:纯数据库方案的延迟不仅更低,而且更加稳定。这让我们开始认真评估 Redis 缓存层存在的必要性。
迈向更简洁的架构
我们并非一次性删除 Redis,而是分阶段、按路由将流量迁移至直接访问 PostgreSQL。最终的架构回归极简:
Clients
|
v
+---------+
| API |
+---------+
|
v
+---------------+
| PostgreSQL |
+---------------+
在此过程中,我们充分利用了 Postgres 18 的新特性:
- 虚拟生成列:将计算逻辑下推到数据库,简化读操作。
CREATE TABLE invoices (
id BIGSERIAL PRIMARY KEY,
customer_id BIGINT NOT NULL,
amount_cents BIGINT NOT NULL,
tax_rate NUMERIC(4,2) NOT NULL,
total_cents BIGINT GENERATED ALWAYS AS (
ROUND(amount_cents * (1 + tax_rate))
)
);
- 增强的 JSON 支持:如
JSON_TABLE,避免了为复杂投影数据单独建立缓存层。
当确认生产环境负载平稳后,我们最终移除了仪表盘流量对 Redis 的依赖。监控显示,数据库的读 I/O 虽有上升,但 CPU 负载依然健康,整体用户延迟变得更优且更稳定。
何时不应移除缓存层
必须强调,本文并非宣告 Redis 已无用处。在以下场景中,独立的缓存层依然至关重要:
- 流量剧烈波动的场景:即使有异步 I/O,数据库也难以应对瞬间的极高读压力。
- 高频写入与全局计数:例如计数器、排行榜,Redis 的数据结构和性能仍是首选。
- 跨服务数据共享:当数据并非由单一数据库作为事实来源时,Redis 是优秀的共享存储中间件。
- 数据库可用性要求极高:如果数据库重启对业务影响巨大,缓存层可作为重要的缓冲带。
总结与启示
Postgres 18 的进步让我们有机会重新审视架构的复杂性。最大的收益并非仅仅是延迟的降低,更是一种思维模式的转变:从机械地遵循“缓存-数据库”二分法,转变为基于实际性能数据和业务场景进行精细化架构决策的能力。
对于后端工程师而言,这意味着你不再仅仅是图纸的实现者,而是能判断“数据库能否承载全部负载”的决策者。Postgres 18 提供了强大的工具,但“何时删除缓存”永远是结合真实压测、流量模式和工程判断后做出的谨慎选择。这种基于深度理解的架构简化,比运行任何特定版本的中间件都更有价值。