缓存与数据库双写场景下,先更新数据库再删除缓存仍出现脏数据,请分析可能原因并给出降低不一致窗口的工程方案。
进阶版来源:alibaba中级工程师并发读写时序延迟双删脏数据窗口缓存与数据库一致性
草稿
答案解析
在缓存和数据库双写场景下,先更新数据库,再删除缓存是比较常见的 Cache Aside 模式,但它只能降低不一致概率,不能完全避免脏数据。
常见原因有几类:
1. 并发读写导致旧值回写缓存
典型时序是:
这样即使 B 已经更新了数据库并删除了缓存,A 仍然可能把旧数据重新放回缓存,后续读到的就是脏数据。
2. 数据库事务未提交就删除缓存
如果更新数据库和删除缓存在事务中处理不当,比如数据库还没提交就先删缓存,这时候其他请求缓存未命中,去数据库读到的还是旧值,然后又写回缓存,也会产生脏数据。
所以删除缓存一般要放在事务提交之后执行,不能在事务未提交时就删。
3. 删除缓存失败
数据库更新成功了,但删除 Redis 失败,比如网络抖动、Redis 超时、客户端异常,这时旧缓存还在,就会继续被读到。
4. 主从延迟导致读到旧数据
如果系统是读写分离,更新写主库,删除缓存后,下一次缓存
登录后查看完整内容
