
上周二,我一口气删掉了 847 行 Redis 代码。
周三,我的技术负责人删了 1,200 行。
到周五,我们的初级工程师删了 2,100 行。
我们没有商量,没有开会,没有写冗长的技术提案。
我们只是都看了 同一组真实的生产基准测试数据,然后得出了同一个结论:我们正在为一层已经不再必要的基础设施付钱。
这不是一篇关于数据库性能的理论文章,而是一个真实的故事,讲述了 PostgreSQL 18 是如何亲手颠覆我坚持了六年的、关于缓存必要性的信仰。
我曾经为之辩护了3年的架构
在做出改变之前,我们系统的结构是这样的:
┌─────────────────────────────────────────┐
│ Application │
└─────────────────┬──────────────────────┘
│
▼
┌────────────────┐
│ Redis │ ≈ 0.1ms
│ (Cache) │
┌────────────────┘
│
▼
┌────────────────┐
│ PostgreSQL │ ≈ 5–15ms
│ (Storage) │
└────────────────┘
↑
cache invalidation hell
这套架构出自我手。我曾无数次在设计评审会上为它辩护,撰写文档解释为什么这是“正确的做法”,甚至还批量培训新人,教他们如何与繁琐的缓存失效逻辑共舞。
三年来,我维护的不仅仅是缓存,还包括:
- 847 行缓存逻辑,分散在 12 个文件里。
- 一个每月 $340 的托管 Redis 集群。
- 每季度至少出现两次 的缓存失效 Bug。
- 两套完全不同的监控面板和 On-Call 手册。
- 一个我不断用“这就是工程现实”来安慰自己的巨大心智负担。
我甚至曾为这套复杂性感到一丝骄傲,它让我觉得自己像一个解决了真实难题的高级工程师。
直到 2025 年 9 月,PostgreSQL 18 的发布改变了一切。
PostgreSQL 18:真正把我脑子敲碎的时刻
PostgreSQL 18 引入了一个关键功能:Asynchronous I/O (AIO,异步 I/O)。
官方发布说明写得非常克制:“新的 I/O 子系统,可提升顺序扫描、位图堆扫描、清理(VACUUM)等操作的性能。”
这句话在技术上是精准的,但在情感上毫无冲击力。让我用更直白的语言解释这意味着什么。
旧的 PostgreSQL
就像一个非常礼貌但刻板的图书管理员:
- 你要一本书。
- 他走过去。
- 拿回来。
- 交给你。
- 然后你再要下一本。
一次只做一件事,秩序井然,但也非常慢。
PostgreSQL 18
这位管理员突然意识到:自己原来有两只手,而且可以一次抱很多本书。
你要10本书,他一次全给你抱过来,“啪”一声放在你桌上。完事。
技术核心是:io_uring 与 Linux 内核的深度集成。
用人类的话说就是:PostgreSQL 终于学会同时干多件事了。
官方宣称性能提升 2-3 倍,但我对这类数据库基准测试的信任度是零——我认为这是基本的职业素养。所以,我决定用 我们真实的生产查询 来验证。
改变一切的那组数字
我们有一个非常典型的看板查询,每天要运行上百万次:
SELECT date, sum(events)
FROM activity
WHERE user_id = $1
AND date > now() - interval '30 days'
GROUP BY date;
测试结果如下:
PostgreSQL 17
PostgreSQL 18(开启 AIO 后)
我反复跑了 4 次,因为起初我无法相信自己的眼睛。
不到 3 毫秒,查询30天的数据,没有 Redis,没有缓存层,仅仅依靠 PostgreSQL 自身。
那个让人不舒服的算术题
是的,Redis 的读取性能可以轻松达到 0.1ms,听起来是无敌的。
但现实世界并非实验室,我们需要考虑所有因素:
- 缓存命中率:73%(这是我们的实际数据)。
- 缓存未命中:需要15ms查询数据库,然后写入 Redis。
- 序列化/反序列化成本:约0.3ms。
- Redis 网络往返延迟(RTT):约0.8ms。
- 缓存失效 Bug 带来的事故处理成本:无法用金钱简单衡量,且频繁发生。
计算加权平均延迟后,我们得到了一个惊人的数字:
引入 Redis 缓存后的实际平均延迟 ≈ 4.2ms
而 PostgreSQL 18(无缓存)的直接查询延迟是:
≈ 2.1ms
我对着这个对比结果沉默了许久。
让这一切成为现实的配置(只有5行)
性能的提升并非来自复杂的架构改造,仅仅是 PostgreSQL 配置文件中新增的几行:
io_method = 'io_uring'
effective_io_concurrency = 200
maintenance_io_concurrency = 50
shared_buffers = 16GB
io_combine_limit = 512kB
是的,就这些。
- 没有修改一行应用代码。
- 没有调整整体架构。
- 没有启动一个耗时半年的迁移项目。
我们在周三部署了新配置,周四就看到看板查询延迟下降了 47%。到了周五,团队的三名成员不约而同地开始删除各自负责模块中的 Redis 缓存代码。
真正被忽略的杀手功能:Skip Scans
除了 AIO, PostgreSQL 18 还有一个被严重低估的特性:B-tree Skip Scans。
我们有一个复合索引:(user_id, status, created_at)。
但很多查询却长这样,缺少了索引的第一列 user_id:
SELECT * FROM orders
WHERE status = 'pending'
AND created_at > '2025-01-01'
ORDER BY created_at DESC
LIMIT 50;
在 PostgreSQL 17 中:
- 这个查询用不上那个复合索引。
- 要么全表扫描,要么选择次优的执行计划。
- 我们当时的解决方案是:用 Redis 配合 TTL 做一层缓存来兜底。
在 PostgreSQL 18 中:
- 优化器会自动“跳过”索引的第一个列 (
user_id)。
- 对每个不同的
user_id 执行高效的范围扫描。
- 结果是:索引被成功利用。
性能提升立竿见影:
45ms → 8ms
同样,没有缓存,没有 TTL 逻辑,没有缓存失效的烦恼。
三年Redis的真实成本(远不止账单)
1. 直接基础设施成本
2. 处理缓存Bug的工程时间成本
- 共发生 23 次相关事故。
- 平均每次处理耗时 7 小时。
- 按每小时 $150 的工程师成本计算。
- 总计约 $24,150。
3. 开发速度的隐性损失
- 每个新功能都要先考虑缓存策略。
- 每次数据库 Schema 改动都要同步思考缓存 Key 的设计。
- 每次部署都要担心缓存预热(Warm-up)问题。
- 保守估计,这导致了 至少 15% 的开发效率损失。
4. 无法量化的心智负担
每一次代码审查、故障调试、系统设计,大脑里都必须额外加载一套缓存模型,这种持续的上下文切换消耗是真实存在却难以统计的。
保守估算,过去三年我们为这套“未经验证的”缓存方案付出的总成本超过 $36,000。而我们最初引入它,竟从未认真衡量过它是否真的必要。
Redis仍然不可替代的领域(请别误会)
我并非在给 Redis 写讣告。它在其核心领域依然是无可争议的王者:
- 会话存储:对延迟和抖动有极致要求。
- 限流:
INCR 和 TTL 的组合简单高效。
- 发布/订阅。
- 排行榜/有序集合。
- 分布式锁。
我们现在更清晰的架构是:
Application
├── Redis(专用于 Session / Rate Limit / 分布式锁等)
└── PostgreSQL 18(承载其他所有业务数据和查询)
系统变得更简单、更经济、更稳定,新同事也更容易理解。
那个真正让我反思的问题
我的代码库中,有多少决策是基于“高级工程师都这么干”,而不是基于“我们实际测量过,这样确实更快”?
我一开始就引入 Redis,并非因为数据证明了其必要性,而是因为它 “看起来像”一个专业的、标准的架构。
PostgreSQL 的开发团队花了多年时间,重写 I/O 子系统、深度集成 Linux 内核、修复无数边界情况……最终,他们让我那 847 行精心维护的缓存代码 看起来像什么?
像一组从未被实际数据验证过的、昂贵的假设。
何时你仍需要谨慎对待此方案
请冷静评估你的场景,以下情况可能并不适合:
- P99 延迟要求必须低于 2ms:此时 Redis 可能仍是必需品。
- 存在百万 QPS 级别的热 Key:Redis 的内存处理能力更合适。
- Linux 内核版本低于 5.10:不支持
io_uring,无法启用 AIO。
- 存储磁盘仍是 HDD:I/O 层面的优化效果会大打折扣。
- 云服务商尚未支持 PostgreSQL 18 的 AIO:需要确认你的环境是否可用。
这不是一场非此即彼的宗教战争,而是一个需要基于自身数据和环境做出的工程判断。
最重要的结论
在每个代码库中,都可能存在一些:
- 曾经合理,
- 现在却无人质疑,
- 但实际上已经过时的复杂性。
PostgreSQL 18 只是迫使我正视了其中之一。
我删除那 847 行代码的唯一原因是:我终于去测量了,并且相信了数据。
也许,你也应该用真实的数据,重新审视一下你系统中那些“理所当然”的复杂性了。如果你想与更多开发者交流此类架构优化经验,欢迎来 云栈社区 的 数据库/中间件 板块参与讨论。