2. 缓存一致性概念
2.1 缓存一致性定义
缓存一致性(Cache Consistency)是指在分布式系统中,缓存层与后端数据库(主数据源)之间数据状态的等价关系。当数据库中的数据发生变更(INSERT / UPDATE / DELETE)时,缓存中对应的副本必须同步更新或失效,使得任何时刻从缓存读取的数据与数据库中的最新数据保持一致。
在 PostgreSQL 逻辑复制驱动缓存的场景中,缓存一致性直接决定了业务能否读到“正确”的数据。如果缓存与数据库出现偏差,轻则返回过期数据,重则引发脏读、重复提交、库存超卖等严重故障。
核心原则:缓存一致性不是“缓存与数据库数据完全相同”,而是“缓存数据在业务可接受的时间窗口内与数据库逻辑等价”。
2.2 读写缓存模型
根据缓存更新策略的不同,读写缓存模型主要分为以下三种:
| 模型 | 写入策略 | 读取策略 | 典型场景 |
|---|---|---|---|
| Cache-Aside(旁路缓存) | 应用先写数据库,再删除/更新缓存 | 先读缓存,未命中则读数据库并回填缓存 | 读多写少,容忍短暂不一致 |
| Read-Through / Write-Through(穿透读写) | 缓存层代理写入,同步写数据库和缓存 | 缓存层代理读取,缓存未命中由缓存层加载数据库数据 | 强一致性要求高,缓存与数据库耦合紧密 |
| Write-Behind(异步回写) | 应用只写缓存,缓存异步批量写回数据库 | 直接从缓存读取 | 写吞吐极高,可接受数据丢失窗口 |
PostgreSQL 逻辑复制驱动的缓存失效/更新通常采用 Cache-Aside + 订阅端回调 的混合模型:逻辑复制槽捕获数据库变更,通过解码输出到消费端,消费端再执行缓存删除或更新操作。
2.3 最终一致性与强一致性对比
在缓存与数据库之间,一致性模型的选择直接影响系统可用性、性能和故障排查复杂度。
| 对比维度 | 强一致性(Strong Consistency) | 最终一致性(Eventual Consistency) |
|---|---|---|
| 定义 | 写入操作完成后,后续任何读取都能立即读到最新值 | 写入后允许短暂不一致,但保证在有限时间内所有副本收敛到最新值 |
| 实现方式 | 同步写缓存 + 分布式锁 / 事务性缓存 | 异步复制 + 过期失效 + 补偿机制 |
| 延迟 | 高(等待所有副本确认) | 低(异步处理,不阻塞主流程) |
| 吞吐量 | 低(串行化写入瓶颈) | 高(批量异步写入) |
| 故障影响 | 写入失败则整体不可用 | 短暂读到脏数据,但系统持续可用 |
| PostgreSQL 逻辑复制场景 | 需同步复制 + 同步消费端确认,延迟极低但性能受限 | 异步逻辑复制 + 缓存 TTL + 重试队列,最常用方案 |
实践建议:在 PostgreSQL 逻辑复制驱动缓存的架构中,绝大多数业务场景选择最终一致性。强一致性通常只在金融交易、库存扣减等场景中局部使用,且需要配合同步复制和分布式事务。
最终一致性在逻辑复制中的典型时间线如下:
- 应用写入 PostgreSQL —— 事务提交成功,数据库已是最新状态。
- 逻辑复制解码延迟 —— WAL 日志被解码并传输到消费端,通常毫秒级,但可能因网络或消费积压而增大。
- 消费端执行缓存失效 —— 删除或更新缓存中的旧数据。
- 缓存收敛 —— 后续读请求命中新数据或重新从数据库加载。
这个时间窗口(步骤 1 → 步骤 4)就是“不一致窗口”。窗口大小取决于逻辑复制的延迟、消费端的处理速度以及缓存的 TTL 策略。