一、先更新数据库,后更新缓存
场景
1)线程A未命中缓存
2)线程A查询数据库
3)线程B写入数据库
4)线程B更新缓存
5)线程A更新缓存
造成缓存脏数据。
二、先删除缓存,后更新数据库
场景
(1)请求A进行写操作,删除缓存
(2)请求B查询发现缓存不存在
(3)请求B去数据库查询得到旧值
(4)请求B将旧值写入缓存
(5)请求A将新值写入数据库
三、先更新数据库,后删除缓存
场景
1)缓存刚好失效
2)请求A查询数据库,得到一个旧值
3)请求B将新值写入数据库
4)请求B删除缓存
5)请求A将旧值写入缓存(读比写慢的情况)
解决方案
①过期时间,保证最终一致性
②延时双删策略
//伪代码
public void write(String key, Object value) {
redis.delKey(key);
db.update(value);
Thread.sleep(1000); //将一定时间内所造成的脏数据删除
redis.delKey(key); //**可以异步处理**
}
如果第二次删除失败,加入重试机制
消息队列重试
订阅binlog重试