【夯实Redis】如何保证数据库与缓存双写一致性?
目录
一、更新操作
数据库与缓存双写一致性问题普遍出现在更新操作中。
先更新数据库,再更新缓存
一般来说,不这么推荐。原因是有些缓存数据是多张数据表联合计算出来的,那么就要求在每次更新以后就要同步计算出新的值,然后更新缓存,这样效率很低。如果是写入场景比较多的业务,那么这种方式会很大程度的降低系统性能。
先更新数据库,再删除缓存
如果先更新数据库,再删除缓存的话,还是有可能造成数据库与缓存双写不一致性。
例如,线程A在更新操作成功之前,线程B读取了旧值。线程A在删除缓存之后,线程B又把旧值存入了缓存。这样缓存中存放的是旧值,而数据库中存放的是新值,就出问题了。
先删除缓存,再更新数据库,最后再次删除缓存
想要解决这个问题,需要在按照下面的步骤。
先删除缓存,再更新数据库,最后休眠后再删除缓存。
在更新操作之前先删除了缓存,用户读取的数据也是数据库的旧值,然后把旧值存放到了缓存中,这没有出现双写一致性问题。
更新数据库成功后,休眠后再次删除缓存,目的是删除其它线程存入的老版本的数据。可把缓存的旧数删除。
当然这种方式会降低系统的吞吐量。
另外,需要为缓存设置过期时间。
其实从根本上此方案还是没有解决双写一致性的问题,比如有一个线程网络特别差,读取了旧值,然后过了很长时间后,再把旧数据存入了缓存中。。。尴尬,这样就又会出现问题。
所以,解决双写一致性性的问题,还是保证原子性,需要使用同步锁。
二、新增操作
新增操作就很简单了,因为之前在缓存中没有数据,所以必须先执行新增操作,然后再把数据给缓存。
整体流程图如下。
参考文章:浅析数据库与缓存的双写一致性问题