Redis维护缓存的方案选择

Redis中间件常常被用作缓存,而当使用了缓存的时候,缓存中数据的维护,往往是需要重点关注的,尤其是重点考虑的是数据一致性问题。以下是维护数据库缓存的一些常用方案。

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

导致数据不一致的场景:

Redis维护缓存的方案选择_第1张图片

最终结果:数据库存储的是新值,缓存存储的是旧值,导致数据不一致

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

Redis维护缓存的方案选择_第2张图片

最终结果:A线程删除缓存失败,导致缓存中一直存的是旧值。但是实际上,删除缓存失败这个异常场景不在此范围讨论中(可以加入重试机制),因此,此方案数据一致性问题不大,但是可能导致穿透问题(缓存数据删除后,瞬间大量请求穿过缓存,直接打到数据库。但是,但凡是删除缓存都有可能导致穿透问题)

3、先更新数据库,然后更新缓存

Redis维护缓存的方案选择_第3张图片

最终结果:更新缓存的时间不确定,有先有后,可能导致旧值覆盖新值的问题。而且性能不好,一万次请求就得更新一万次缓存。

4、延时双删

在方案一的基础上,增加了一次删除缓存的操作。回想方案一,导致数据不一致的问题是,A线程在B线程之后更新完数据库后,没有去处理缓存数据。因此,在更新完数据库后,再删除一次缓存便可(本质上就是方案一与方案二的结合)

总体流程:先删除缓存,然后再更新数据库,更新完数据库后,延时再删除一次缓存,做兜底操作。

更新数据库前删一次缓存,是因为,防止在更新数据库后的瞬间,有人直接命中缓存,拿到旧数据

更新数据库后再删一次缓存,是因为,有人通过查库拿到旧数据,设置值进了缓存(方案一数据不一致的情况),之所以要延时,是因为要保证,第二次删除的时机要在其他人写数据之后,否则白删。

注意:既然是删除缓存数据,依然会导致缓存穿透的问题。

根据实际业务场景,我选择了方案三:先更新数据库,再更新缓存。原因如下:

1、修改缓存的入口只有一个,在控制台中设置,不存在多个线程修改缓存的情况

2、读的入口有多个,有许多定时器会在自己的业务中读缓存值,有并发且量十分大,因此,需要考虑缓存穿透问题(不能删除缓存)

3、缓存中存的实际是业务配置,读多写少,大量更新操作导致性能消耗的场景不存在

每一种方案都存在他的优缺点。在理想中,我们往往希望能适用所有场景的方案,但是,现实往往很骨感,一劳永逸的方法几乎只存在于某个乌托邦。方案没有好坏之分,只有是否适合自己的应用场景之别。

Redis维护缓存的方案选择_第4张图片

你可能感兴趣的:(缓存,redis,数据库)