商品价格更新后,用户偶尔还能看到旧缓存,你们如何控制缓存与数据库的不一致窗口?
我的判断
商品价格以数据库为准,更新采用先提交数据库再删除缓存,并用消息或延迟重试把删除失败的不一致窗口收敛。
我通常使用 cache-aside:读请求 miss 后查库并写缓存;价格更新在数据库事务提交成功后删除缓存,而不是直接更新缓存。下一次读取会回源拿新值,避免同时维护两份复杂状态。
仍有一个竞态:旧读请求先查到旧价格,更新事务提交并删缓存后,旧读又把旧值写回。会通过较短 TTL、带版本的缓存值,或订阅 binlog/业务事件再次失效来收敛;高价值价格读取可以比较版本,拒绝覆盖更新版本。
删除缓存失败不能只记日志。我会把变更事件放可靠消息/outbox,消费者按商品 ID 幂等删除并重试,监控消息延迟和失败数。
业务还要定义允许窗口:商品列表允许几秒旧值,结算金额必须重新从权威服务校验。缓存一致性不是所有页面都追求“瞬时强一致”,而是把错误价格影响控制在明确边界。
思路拆解问题分析
一致性的核心不是“先删还是后删”口令,而是找出并发读写的时序、失败后的补偿通道,以及最终哪个环节必须再次校验权威数据。