微信搜索关注「水滴与银弹」公众号,第一时间获取优质技术干货。7年资深后端研发,给你呈现不一样的技术视角。
你好,我是 Kaito。
如何保证缓存和数据库一致性,这是一个老生常谈的话题了。
但很多人对这个问题,依旧有很多疑惑:
- 到底是更新缓存还是删缓存?
- 到底选择先更新数据库,再删除缓存,还是先删除缓存,再更新数据库?
- 为什么要引入消息队列保证一致性?
- 延迟双删会有什么问题?到底要不要用?
- …
这篇文章,我们就来把这些问题讲清楚。
这篇文章干货很多,希望你可以耐心读完。

引入缓存提高性能
我们从最简单的场景开始讲起。
如果你的业务处于起步阶段,流量非常小,那无论是读请求还是写请求,直接操作数据库即可,这时你的架构模型是这样的:

但随着业务量的增长,你的项目请求量越来越大,这时如果每次都从数据库中读数据,那肯定会有性能问题。
这个阶段通常的做法是,引入「缓存」来提高读性能,架构模型就变成了这样:

当下优秀的缓存中间件,当属 Redis 莫属,它不仅性能非常高,还提供了很多友好的数据类型,可以很好地满足我们的业务需求。
但引入缓存之后,你就会面临一个问题:之前数据只存在数据库中,现在要放到缓存中读取,具体要怎么存呢?
最简单直接的方案是「全量数据刷到缓存中」:
- 数据库的数据,全量刷入缓存(不设置失效时间)
- 写请求只更新数据库,不更新缓存
- 启动一个定时任务,定时把数据库的数据,更新到缓存中

这个方案的优点是,所有读请求都可以直接「命中」缓存,不需要再查数据库,性能非常高。
但缺点也很明显,有 2 个问题:
- 缓存利用率低:不经常访问的数据,还一直留在缓存中
- 数据不一致:因为是「定时」刷新缓存,缓存和数据库存在不一致(取决于定时任务的执行频率)
所以,这种方案一般更适合业务「体量小」,且对数据一致性要求不高的业务场景。
那如果我们的业务体量很大,怎么解决这 2 个问题呢?
缓存利用率和一致性问题
先来看第一个问题,如何提高缓存利用率?
想要缓存利用率「最大化」,我们很容易想到的方案是,缓存中只保留最近访问的「热数据」。但具体要怎么做呢?
我们可以这样优化:
- 写请求依旧只写数据库
- 读请求先读缓存,如果缓存不存在,则从数据库读取,并重建缓存
- 同时,写入缓存中的数据,都设置失效时间

这样一来,缓存中不经常访问的数据,随着时间的推移,都会逐渐「过期」淘汰掉,最终缓存中保留的,都是经常被访问的「热数据」,缓存利用率得以最大化。
再来看数据一致性问题。
要想保证缓存和数据库「实时」一致,那就不能再用定时任务刷新缓存了。
所以,当数据发生更新时,我们不仅要操作数据库,还要一并操作缓存。具体操作就是,修改一条数据时,不仅要更新数据库,也要连带缓存一起更新。
但数据库和缓存都更新,又存在先后问题,那对应的方案就有 2 个:
- 先更新缓存,后更新数据库
- 先

本文深入探讨了缓存和数据库一致性问题,分析了更新缓存与删除缓存的策略及其潜在的问题,如并发、主从延迟等。提出了先更新数据库再删除缓存的方案,结合消息队列或订阅数据库变更日志来保证数据最终一致性的实践方法。同时,讨论了如何应对延迟双删问题和追求强一致性的挑战。
最低0.47元/天 解锁文章
1223

被折叠的 条评论
为什么被折叠?



