微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

保证mysql和redis的双写一致性

一、场景:双写一致性指的是当我们更新了数据库的数据之后redis中的数据也要同步去更新。使用redis读取数据的流程,当用户访问数据的时候,会先从缓存中读取数据,如果命中缓存的话,那么直接把缓存中的数据返回给用户,如果缓存中没有数据的话,先查询数据库查询到的数据保存到缓存中,然后返回给用户

在这里插入图片描述

二、保证双写一致性的策略
1.先更新缓存,再更新数据库
2.先更新数据库,再更新缓存
3.先删除缓存,再更新数据库
4.先更新数据库,再删除缓存

三,四种策略的优缺点
1.先更新缓存,再更新数据库
问题很明显如果更新缓存成功,更新数据库失败,就会造成缓存的脏数据
2.先更新数据库,再更新缓存
如果再高并发的情况下,可能会存在如下的情况,线程A更新了数据库,如果由于网络或者其他的原因,线程A还没来得及更新缓存,这时候有一个进程B更新了数据库,更新了缓存,这时候进程A才更新缓存,这时候就会导致线程B对缓存的更新丢失了,像事务丢失的情况
3.先删除缓存,再更新数据库
这种策略可能已经避免掉了,策略2中缓存丢失的情况,但是再高并发的情况下,也会有不一致的情况,比如线程A做写操作,首先删除缓存然后准备跟新数据库,这时候,线程B执行了写操作,没有命中缓存,然后查询数据库,这时候读取的是旧值,并把查询到的旧值保存到缓存中,接着线程A完成了数据库的更新,这时候数据库和缓存又出现了不一致的情况,解决方案:我们只要再线程A,完成数据库的更新之后,稍作延迟再删除一次缓存,也叫做延迟双删。这里的延迟时间一定要大于业务的一次读操作的时间。
4.先更新数据库,再删除缓存
再高并发的情况下,也会有不一致的情况,比如线程A做读取数据的操作,正准备写入缓存的时候,线程B更新了数据库,然后执行删除缓存的操作,这时候线程A才把旧值写入到缓存中,虽然这种情况出现的概率比较低,因为写操作的时候要大于一次读操作的时间的解决方案:延迟双删,延时双删还是又问题的,如果删除缓存失败怎么办,当然是再次删除,不断的循环删除删除失败后我们可以将要删除的key放入到队列中,然后尝试重复删除,直到删除成功。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐