数据库与Redis保持缓存一致性问题
旁路缓存模式
这是平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景。
写:先更新 DB,然后直接删除 cache 。
读:从 cache 中读取数据,读取到就直接返回,cache中读取不到的话,就从 DB 中读取数据返回,再把数据放到 cache 中。
问题 “在写数据的过程中,可以先删除 cache ,后更新 DB 么?”
答:不行,因为这样可能会造成数据库(DB)和缓存(Cache)数据不一致的问题。请求1先把缓存中的A数据删除,然后请求2就从数据库读取数据,请求1再修改数据库中的A数据。
在写数据的过程中,先更新DB,后删除cache就没有问题了么?”
答:理论上来说还是可能会出现数据不一致性问题。
缺陷1:首次请求数据一定不在 cache 的问题
解决办法:可以将热点数据可以提前放入cache 中。
缺陷2:写操作比较频繁的话导致cache中的数据会被频繁被删除,这样会影响缓存命中率 。
解决办法:
数据库和缓存数据强一致场景 :更新DB的时候同样更新cache,不过我们需要加一个锁/分布式锁来保证更新cache的时候不存在线程安全问题。
可以短暂地允许数据库和缓存数据不一致的场景 :更新DB的时候同样更新cache,但是给缓存加一个比较短的过期时间,这样的话就可以保证即使数据不一致的话影响也比较小。
读写穿透模式
写:先查 cache,cache 中不存在,直接更新 DB。cache 中存在,则先更新 cache,然后 cache 服务自己更新 DB
读:从 cache 中读取数据,读取到就直接返回 。读取不到的话,先从 DB 加载,写入到 cache 后返回响应。