怎么保证缓存和数据库数据的一致性?

淘汰缓存还是更新缓存? 

选择淘汰缓存

原因:数据可能为简单数据,也可能为较复杂的数据,复杂数据进行缓存的更新操作,成本较高,因此一般推荐淘汰缓存

先淘汰缓存还是先更新数据库?

选择先淘汰缓存,再更新数据库

原因:假如先更新数据库,再淘汰缓存,假如缓存淘汰失败,那么后面的请求都会得到脏数据,直至缓存过期。假如先淘汰缓存再更新数据库,如果数据库更新失败,只会产生一次缓存miss,相比较而言,后者对业务影响更小一点。

延时双删策略

如下场景:同时有一个请求A进行更新操作,另一个请求B进行查询操作。
(1)请求A进行写操作,删除缓存
(2)请求B查询发现缓存不存在
(3)请求B去数据库查询得到旧值
(4)请求B将旧值写入缓存
(5)请求A将新值写入数据库

次数便出现了数据不一致问题。采用延时双删策略得以解决

public void write(String key,Object data){
    redisUtils.del(key);
    db.update(data);
    Thread.Sleep(100);
    redisUtils.del(key);
}

这么做,可以将1秒内所造成的缓存脏数据,再次删除。这个时间设定可根据俄业务场景进行一个调节。

数据库读写分离的场景

两个请求,一个请求A进行更新操作,另一个请求B进行查询操作。

(1)请求A进行写操作,删除缓存
(2)请求A将数据写入数据库了,
(3)请求B查询缓存发现,缓存没有值
(4)请求B去从库查询,这时,还没有完成主从同步,因此查询到的是旧值
(5)请求B将旧值写入缓存
(6)数据库完成主从同步,从库变为新值

依旧采用延时双删策略解决此问题

参考链接:Redis缓存和数据库一致性问题

                   缓存与数据库一致性之一:缓存更新设计

posted @ 2020-01-30 16:25  莫等、闲  阅读(9823)  评论(2编辑  收藏  举报