【夯实Redis】如何保证数据库与缓存双写一致性?

目录

一、更新操作

先更新数据库,再更新缓存

先更新数据库,再删除缓存

先删除缓存,再更新数据库,最后再次删除缓存

二、新增操作


一、更新操作

         数据库与缓存双写一致性问题普遍出现在更新操作中。

先更新数据库,再更新缓存

         一般来说,不这么推荐。原因是有些缓存数据是多张数据表联合计算出来的,那么就要求在每次更新以后就要同步计算出新的值,然后更新缓存,这样效率很低。如果是写入场景比较多的业务,那么这种方式会很大程度的降低系统性能。

先更新数据库,再删除缓存

        如果先更新数据库,再删除缓存的话,还是有可能造成数据库与缓存双写不一致性。

        例如,线程A在更新操作成功之前,线程B读取了旧值。线程A在删除缓存之后,线程B又把旧值存入了缓存。这样缓存中存放的是旧值,而数据库中存放的是新值,就出问题了。

先删除缓存,再更新数据库,最后再次删除缓存

        想要解决这个问题,需要在按照下面的步骤。

        先删除缓存,再更新数据库,最后休眠后再删除缓存。

        在更新操作之前先删除了缓存,用户读取的数据也是数据库的旧值,然后把旧值存放到了缓存中,这没有出现双写一致性问题。

        更新数据库成功后,休眠后再次删除缓存,目的是删除其它线程存入的老版本的数据。可把缓存的旧数删除。

当然这种方式会降低系统的吞吐量。

另外,需要为缓存设置过期时间。

其实从根本上此方案还是没有解决双写一致性的问题,比如有一个线程网络特别差,读取了旧值,然后过了很长时间后,再把旧数据存入了缓存中。。。尴尬,这样就又会出现问题。

所以,解决双写一致性性的问题,还是保证原子性,需要使用同步锁。

                                                        【夯实Redis】如何保证数据库与缓存双写一致性?

二、新增操作

         新增操作就很简单了,因为之前在缓存中没有数据,所以必须先执行新增操作,然后再把数据给缓存。

         整体流程图如下。

                                                                   【夯实Redis】如何保证数据库与缓存双写一致性?

参考文章:浅析数据库与缓存的双写一致性问题