Redis作为缓存和数据库的数据一致性问题

Redis作为缓存和数据库的数据一致性问题

使用Redis作为缓存了,但是会有一个问题,就是当修改了数据库中的数据,这个时候缓存中响应的数据就和数据库不一致了,这个时候应该怎么办呢?注意:本文只关注最终会导致缓存和数据库中数据不一致的情况。

数据更新操作

数据更新操作,也就是对数据库执行update执行更新操作。那么对数据进行修改的同时也需要对Redis中缓存执行一些操作来解决数据不一致的问题,那么应该对Redis中的缓存数据执行同步修改操作还是删除操作呢?

修改还是删除?

首先看更新数据库后是去更新缓存操作,考虑下面两种情景:

**情景1:**用户修改自己的用户名,修改了一次后不满意,就又修改了一次,但是最后显示的却是第一次修改的用户名,第二次修改的没有显示出来。这是为什么。

首先在这期间共发起了四次请求,线程A执行第一次修改,线程B执行查询,线程C执行第二次修改,线程D执行第二次查询。着重看两次修改的线程。这是导致缓存和数据库数据不一致的关键。

如果线程A先更新数据库后,但是出现了网络延迟,缓存的更新操作延迟了,线程C更新了数据库,立马又更新了缓存,此时线程A的缓存更新操作完成了,于是,缓存中的数据就是线程A的更新数据,而数据库中的数据是最终线程C的更新数据,这就造成了数据不一致。

**情景2:**当前是写多读少的程序,用户执行了1000次修改操作,但是最后才执行了1次查询操作。那么此时就会进行1000次数据库的修改和缓存的修改,但是缓存的前999次修改都是无效的,造成了大量的时间和空间浪费,删除操作又比修改操作快,而且无数据时删除操作是不执行的。所以删除缓存是最好的选择而不是更新。

最终我们选择更新完数据库后进行删除操作

先数据库还是先缓存

我们已经知道是更新数据库,删除缓存这两个操作。那么是先更新数据库还是先删除缓存呢?同样,从用户场景出发。

先删除缓存,再更新数据库:因为对数据库操作是很慢的,而对缓存操作是很快的,所以很容易出现下面一个情景:线程A先更新数据,线程B再读取数据,线程A删除了缓存,但是由于更新数据库的速度很慢,事务还未提交,线程B又进来了,它读取缓存但是缓存被删了就去读数据库,读取到了数据库中的数据返回给了客户端,同时将数据写到了缓存中,最后线程A更新数据库的操作终于完成了。这时,数据库中保存的确实是最终修改后的新值,但是缓存中却保存着更新前的旧值。同样造成了数据不一致问题。

**先更新数据库再删除缓存:**这种操作的话,也可能会出现数据不一致的问题。就是线程B读缓存,未读到,然后去查询了数据库,但是写入缓存的时候延迟了,这时候线程A更新了数据库,并删除了缓存。最后线程B才将数据库查到的数据写入缓存。这时候缓存就是旧值,数据库中就是新值。但是由于缓存操作肯定会快于数据库操作,所以发生概率不大。但同样也有可能,所以也可以有一些策略来解决:延迟双删操作(更新数据库->第一次删除缓存---->延迟一段时间第二次删除缓存)

设置过期时间

上面所有的操作都只能尽可能地保证数据库和缓存的数据一致,但是就像没有十全十美的人一样,软件也做不到完美,所以总会有疏漏,所以在缓存上添加一个过期时间,在一段时间后自动删除,下次再获取就需要从数据库中获取数据再写入缓存,这样也保证了一致性。这也是最后的兜底方案了。

相关推荐
Decay__38 分钟前
05_MySQL 常用 SQL 大全 —— 诊断、管理、优化辅助 SQL 与三大系统库速查
运维·数据库·sql·mysql·架构
小徐不徐说5 小时前
C++ 接口与插件设计:从工厂注册到 Qt 动态插件
数据库·c++·qt·系统架构·程序设计
论文复现现场5 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
Decay__6 小时前
04_MySQL DBA 日常运维手册 —— 会话管理、锁与阻塞、事务监控、慢查询与日志巡检
运维·数据库·sql·mysql·架构
心梦缘-雪雁8 小时前
SQL Server 查询数据存在哪个表里
数据库
lusklusklusk8 小时前
Python 巡检脚本:进程运行状态、数据库写入时效检查及邮件通知与告警
数据库·python·oracle
代码丰9 小时前
大 JSON 放进 Redis 之后,如何用 Stream 解耦耗时任务?
redis·后端·系统架构
GeW9 小时前
产业新优势基础软件的人才底盘,从Linux与数据库开始
linux·数据库
SelectDB9 小时前
Doris Arrow Flight SQL 高速读取协议实战:与 Snowflake 客户端取数链路对照
大数据·数据库·数据分析
曼岛_9 小时前
[图解密码学]第4章 古典密码
java·数据库·密码学