您的位置:首页 > 文旅 > 旅游 > Redis双写一致性

Redis双写一致性

2024/10/6 4:08:19 来源:https://blog.csdn.net/weixin_61787820/article/details/139841543  浏览:    关键词:Redis双写一致性

双写一致性

当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致。

注意这里是对数据库进行写操作而不是读操作,通常我们有两种方式完成这个写操作,分别是:先删除缓存再修改数据库 和 先修改数据库再删除缓存,但是这两种方式都存在问题(出现脏数据)。

先删除缓存再修改数据库:

先删除缓存再修改数据库的话,如果在 线程1 删除缓存后有 线程2 对数据进行了查询(此时数据库中的数据仍然是旧数据,且缓存中已经没有数据)并将查询的值写入缓存,那么缓存中存放的就是旧数据,此时 线程1 也完成了对数据库的更新,那么就会出现数据库是新数据而缓存是旧数据的情况。

先修改数据库再删除缓存:

我们这里讨论一种特殊情况,就是缓存中的数据过期了,此时 线程1 去查缓存查不到,就会去访问数据库(此时数据库是旧数据),突然 线程2 横插一脚,它来执行了一个更新数据库的操作,把数据库的数据更新为了新数据,并去删除缓存(虽然缓存中没有数据,不过不影响),线程2 执行完毕后 线程1 继续执行,把它访问数据库(旧数据)的数据更新到缓存中,这样就出现了缓存是旧数据而数据库是新数据的情况。

为了减少脏数据的出现,我们可以使用下面这种方法

延迟双删:

在删除缓存、修改数据库后再次进行一次缓存删除,注意要延时(因为数据库也可能有子节点,需要给时间给主从节点的数据同步),不过延时的时间并不能确定,所以依然有脏数据出现的可能,但是也已经极大的控制了这个可能性。

如果我们的系统有强一致性的要求,就需要使用分布式锁来实现了

分布式锁:

这种方法呢就保证了强一致性,但是性能较差,我们可以用读写锁(ReadWriteLock)优化一下

共享锁readLock,只限制写操作,加了这个锁后不影响别人的读操作(读操作时添加,读读不互斥,读写互斥)

独占锁writeLock,读写都影响(写操作时添加)

毕竟是加锁,其实这种方法的性能也是不高,不过保证了强一致性,在我们对强一致性要求不高(也许延迟一致的时候),可以使用下面两种异步通知的方法。

基于MQ的异步通知:

基于Canal的异步通知:

这种方法更好一点,canal会伪装成mysql的一个从节点,不会对代码进行侵入。

两种异步通知的方法当然都是存在短暂的延迟的,不能保证强一致性,都是最终数据都会变成一致的,我们可以按需选择自己的方法。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com