数据库与redis缓存一致性问题
先更新了缓存,然后数据库也更新了,但是数据库更新失败了,回滚之后就会出现缓存不一致的情况。
或者两个线程更新同一个数据的时候,但是时序不一样,可能存在缓存不一致的问题。
避免这种情况就是删除缓存;
1、后删缓存策略
但是后删缓存仍然存在缓存不一致的情况,当A请求做查询操作,B请求做更新操作,
-
A先读取,但是缓存刚好失效,读取到数据库旧值,
-
B将新值写入到数据库,B将缓存删除
-
此时A将旧值更新到缓存中,此时某些读取改数据的线程就可能读取到旧值
-
然后B在将数据更新到缓存,
在A更新缓存和B更新缓存之间,可能会存在有一些线程读取到旧值(脏数据)。
2、延时双删
- 先删除缓存
- 再更新数据库
- 延迟200ms
- 再删除缓存
3、binglog同步
但是!删除缓存可能会失败,那就把失败的key写进消息队列中,重新从消息队列获取数据,再次删除缓存。
- 更新数据库数据
- 数据库会将操作信息写入binlog日志当中
- 订阅程序提取出所需要的数据以及key
- 另起一段非业务代码,获得该信息
- 尝试删除缓存操作,发现删除失败
- 将这些信息发送至消息队列
- 重新从消息队列中获得该数据,重试操作。