Redis 缓存一致性

巧了我就是萌 提交于 2020-12-14 22:13:37

引入缓存后,随之带来的问题就是DB数据更新时,缓存中的数据会与db数据不一致,这时需要对缓存的数据进行更新或者淘汰缓存

先更新DB还是先操作缓存?

更新DB和操作缓存明显缺乏原子性,有可能更新DB完成,但是缓存操作失败,反之亦然。这里推荐先更新DB 再更新或者淘汰缓存   原因如下:

1 如果先更新缓存的话,然后数据库中数据更新失败了,下一个读请求过来,读到的数据是是未更新的数据库中的数据,这样的数据明显是错误的

2 如果先淘汰缓存,然后更新DB,如果在DB更新完成之前,来了一个新的请求,那么就会查询出数据库中的旧数据,缓存到redis,导致DB更新完成之后,两者数据不一致。

3 如果先更新DB  然后缓存操作失败,客户端读到的是旧数据,此时也存在DB缓存不一致,但是实际业务上,我们还是以DB数据为准,这种读取到旧数据的业务影响可能比读取到未更新到DB的数据影响更小。

如何保持更新DB和操作缓存之间的连续性?

两个动作原则上是非原子性的,一个是更新DB,一个是更新Redis.可以使用消息队列来实现最终一致性的消息保证。   先更新数据库,然后通过发送缓存的消息到消息队列中,进行更新缓存操作,还需要利用消息队列的重试机制,保证缓存能够更新成功,如果多次失败可能是由于网络原因或者是redis服务挂了。

 

更新缓存还是淘汰缓存?
严格来说 不论是更新缓存还是淘汰缓存都可能出现缓存不一致,但是客观上说更新缓存出现缓存不一致的可能性更大。  

* 采用先更新DB  后面更新缓存可能出现的问题。

 1   采用更新缓存的方式 需要考虑操作完DB后,后续的更新缓存操作,是否需要比较复杂的操作才能得到应该set进缓存中值,,例如是否需要复杂计算或者DB交互查询。如果是,那么不建议使用更新缓存,直接使用淘汰换缓存。

2  并发写问题,如果两个写请求同时进行写DB操作,A先于B,B基于A做更新,此时假如是使用传值进行更新缓存,可能出现的问题就是B的写缓存操作,后于A的写缓存操作。从而导致缓存被A的更新的数据覆盖,缓存中的数据变成旧的数据,出现缓存不一致。

3 采用mq重试和告警,更新DB与更新缓存之间也可能存在断层

* 若采用先更新DB,后淘汰缓存可能出现问题

1 采用mq重试和告警  ,更新DB与淘汰缓存之间也可能存在断层。

通过以上分析  可以使用淘汰缓存方案更好,这只是简单的场景,具体场景具体分析。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!