找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

325

积分

0

好友

45

主题
发表于 前天 00:49 | 查看: 6| 回复: 0

图片

一次系统优化中,我关闭了一整套 Redis 集群。没有告警,没有波动,监控延迟曲线在轻微晃动后,反而下降了。这一刻让我意识到,Postgres 18 的性能表现,在某些场景下足以超越我们精心维护的缓存层。

本文将分享这一决策背后的技术细节、Postgres 18 带来的关键变革,以及如何在评估后安全地简化架构。

缓存层成为瓶颈的教训

在过去多年的架构中,我们遵循一个经典模式:应用先查询 Redis,若未命中再查询 PostgreSQL 数据库,并将结果回写到 Redis。我们优化了 TTL 和驱逐策略,自认为架构非常“专业”。

然而,在一次流量高峰中,Redis 集群出现了问题:CPU 使用率达到 90%,网络带宽吃紧,延迟剧烈波动。但与此同时,底层的 PostgreSQL 数据库却非常空闲。这次事件迫使我们反思:投入大量资源维护的缓存层,是否反而成为了系统的瓶颈?

Postgres 18 的性能飞跃

Postgres 18 带来了若干核心改进,正是这些改进让我们重新思考“数据库必须被缓存保护”这条铁律。作为现代应用架构中的核心数据库/中间件,其性能提升直接影响技术选型。

核心升级包括:

  1. 全新的异步 I/O 子系统:能够自动批量合并多个读取请求,使得顺序扫描和位图堆扫描的速度最高可提升 3 倍。
  2. 更智能的索引使用:优化器在多列索引场景下(如跳跃扫描 Skip Scan)的选择更加精准,能更好地遵循开发者的设计意图。
  3. 虚拟生成列:允许将计算派生出的字段直接定义在表中,简化了查询逻辑,减少了对应用程序层计算或缓存填充的依赖。

这些能力的结合,催生了一个大胆的想法:如果数据库自身已经足够快,我们是否还需要独立的缓存层?

一次改变架构观的实验

我们没有贸然行动,而是进行了“暗流量测试”。我们选取了一个典型的、缓存受益显著的查询场景:用户仪表盘数据聚合。

首先,在 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 已无用处。在以下场景中,独立的缓存层依然至关重要:

  1. 流量剧烈波动的场景:即使有异步 I/O,数据库也难以应对瞬间的极高读压力。
  2. 高频写入与全局计数:例如计数器、排行榜,Redis 的数据结构和性能仍是首选。
  3. 跨服务数据共享:当数据并非由单一数据库作为事实来源时,Redis 是优秀的共享存储中间件。
  4. 数据库可用性要求极高:如果数据库重启对业务影响巨大,缓存层可作为重要的缓冲带。

总结与启示

Postgres 18 的进步让我们有机会重新审视架构的复杂性。最大的收益并非仅仅是延迟的降低,更是一种思维模式的转变:从机械地遵循“缓存-数据库”二分法,转变为基于实际性能数据和业务场景进行精细化架构决策的能力

对于后端工程师而言,这意味着你不再仅仅是图纸的实现者,而是能判断“数据库能否承载全部负载”的决策者。Postgres 18 提供了强大的工具,但“何时删除缓存”永远是结合真实压测、流量模式和工程判断后做出的谨慎选择。这种基于深度理解的架构简化,比运行任何特定版本的中间件都更有价值。




上一篇:Python 50个常用开源框架精讲:Web开发、数据分析与AI实战指南
下一篇:网络取证实战:元数据与会话日志核心差异及异常分析指南
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区(YunPan.Plus) ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-6 22:54 , Processed in 0.070452 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 CloudStack.

快速回复 返回顶部 返回列表