这也是一道非常经典的面试题。可以查到它在很多面经中都出现过。还有一个比较的具体问法其实是:如何保证MySQL和Redis的数据一致性?
什么是数据一致性
例如将Redis用作MySQL数据的缓存时,由于数据在MySQL中的变更,导致Redis中的缓存数据与实际数据不一致的情况。这种不一致可能会导致应用程序读取到过期、错误或者不完整的数据,从而影响系统的正确性和可靠性。
解决方案
方案0:同步更新(删除)
在介绍解决方案之前,我们想一想正常的业务流程如何做的,无非是先更新A再更新B(这里的AB无所谓,可能先更新缓存,也可以先更新数据库),但是这个方案有问题。
想想一下的情形:两个请求分别对同一数据进行更改。请求 A、B 都是先写 MySQL,然后再写 Redis,由于某些原因,如果请求 A 在写MySQL之后写 Redis 之前间隔了一段时间,在此期间请求 B 已经依次完成对MySQL和Redis的更新,就会造成下面的问题。
同样先删除Redis,再写MySQL,再写Redis也是同样的道理。因为我们无法保证上述操作的原子性。
方案1:延迟双删
- 1.先删除缓存数据
- 2.更新数据库数据
- 3.等待一小段时间
- 4.再次删除缓存数据
但是这种方法仍然有问题,因为我们无法保证更新请求的第二次删除一定发生在读请求的回写缓存之后。如同下图所示,这样缓存中就存在脏数据
方案2:异步监听binlog+删除重试机制
- 1.更新数据库
- 2.监听binlog删除缓存
- 3.缓存删除失败则通过MQ不断重试,直至成功
唯一的问题就在于异步删除的脏数据时间窗口较大,而且要求查询的请求不会回写Redis。
总结
在满足实时性的条件下,不存在两者完全保存一致的方案,只有最终一致性方案:先写 MySQL,通过 Binlog,异步更新 Redis,可以通过 Binlog,结合消息队列异步更新 Redis。
标签:缓存,试题,删除,Redis,更新,MySQL,金三银,数据 From: https://blog.csdn.net/weixin_45700531/article/details/136985028