Redis 缓存数据库双写不一致

正常情况下,缓存的读取流程如下:

image-20211029163900532

什么是缓存一致性的问题,其实就是我们最终落库数据和我们缓存中的数据不一致

解决方案

1、设置过期时间

这种方案是为缓存的 key 值设置失效时间,这种情况下不管数据库数据怎么折腾,最晚会在缓存失效后,重新从数据库中获取最新的数据,加载到缓存中。

优点:最终缓存内数据和数据库中数据是一致的

缺点:内容更新不及时

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

种这方案的问题在于,当有两个或者多个线程同时进行数据更新时,会发生数据不一致的情况。流程如下图:

image-20211029165743602

当线程 1 先更新数据库,但是由于网路等原因晚于线程 2 更新缓存,最终导致的结果是缓存数据的不一致。

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

此方案问题在于,当有一个线程读取缓存时,缓存已经被另一个更新线程删除了,此时读取线程会去数据库查询数据,并且放到缓存中,此时更新线程还没有完成数据库的更新操作,依旧会出现缓存不一致的问题。流程如下:

image-20211029171055546

这种情况可以采用延时双删的策略,在更新数据库之后,延时一段时间,然后将缓存再次删除掉,这样其他读取线程再次读取时候,还是会加载最新的数据。

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

正常情况如下:

image-20211029171542343

但是,如果我们的读取数据库数据在更新之前,并且更新缓存在删除缓存之后,也同样会出现一致性问题,流程如下:

image-20211029171639686

此时可以加入延时删除策略,由于更新线程最终删除了缓存,所以下次在读取时还会重新载入,流程如下:

image-20211029172406868

5、使用分布式锁

使用分布式锁可以彻底解决这个一致性问题。当更新和读取线程同时加锁,会按照顺序进行执行,这样确实可以杜绝,但是加了锁,在高并发的情况下,大量读取缓存的操作可能会因为锁而排队。

转载整理自:https://blog.csdn.net/wk2yangyang/article/details/106677241