如何保证数据库的数据和Redis的数据一致性

实际项目中有可能会使用Redis缓存数据,那么在更新数据的时候如何保证数据库中的数据和Redis缓存的数据一致,缓存同步策略的选择是一个很重要的问题。网上有各种说法,大概总结有以下几种,看看每种方案是否可行以及存在的问题和适用场景。

1、先更新Redis,再更新数据库 (不可行 )

数据库是比较复杂的,而且还会涉及事务,因为超时等原因更新操作失败的可能性较大,这种方案很可能因为数据库更新失败,导致缓存和数据库的数据不一致。
在这里插入图片描述
如上图所示,如果第2步更新数据库失败了,那么缓存的数据被更新为20,和数据库值10不一致了。

这种情况可能会想到补救措施:数据库更新失败了再将Redis数据做逆向操作进行回退,但是如果Redis数据回退操作也失败了呢?甚至还要继续针对这种失败做重试?显然事情越做越复杂了,这种方式不可行。

2、先更新数据库,再更新Redis (部分场景可用,不推荐 )

上面的方案不可取,这种先更新数据库的是否就可行呢?假设有两个请求更新数据,时序图如下:
在这里插入图片描述

如果是并发量不高,对一致性要求没有特别高时,如上图更新完数据库再更新Redis没有问题。

在这里插入图片描述

如果是并发量较高,如图所示这种场景下虽然请求1和请求2先后完成数据库更新,但更新缓存时却是请求2和请求1的顺序,那就很可能会把旧数据更新到缓存中导致数据不一致。

3、先删除Redis,再更新数据库,访问的时候再加载数据到缓存 (不可行 )

这里同样以两个请求的场景为例,时序图如下:
在这里插入图片描述
从图上可以看到,当并发场景下如果请求1更新耗时较长,还未来得及更新数据库中的值,请求2已经先读取了旧值并加载到缓存中了。这种也会导致两边数据不一致,而且并发量很高的时候这种概率也会更大。

针对这个方案存在的问题可以在请求1更新完数据库后再对Redis做一次删除操作。也就是缓存双删

4、先删除Redis,再更新数据库,再删除Redis,访问的时候再加载数据到缓存(缓存双删)

在这里插入图片描述
这种方案一定程度上解决了方案4数据不一致的问题,但是也有一个关键点,如上图所示必须保证第6步删除缓存操作在第5步回写入缓存操作之后执行,否则还是会有问题。那么这又引出了另外两个问题:

  • 问题一:如何保证第二次删除缓存一定在回写后面执行呢?

关于双删的这个问题网上有方案是让请求1删除缓存时等待xxx毫秒,这个方案似乎可行,但是这个时间不好控制还是会存在一定风险。
另外也有博主给出的建议方案是将删除请求加入消息队列,异步串行化处理删除

  • 问题二:如果双删失败了怎么办?

同样的网上也有方案:给redis加一个缓存过期时间、删除加入消息队列利用消息队列的重试机制、自己记录删除失败进行重试等

5、先更新数据库,再删除Redis,访问的时候再加载数据到缓存

在这里插入图片描述
这种方案除了请求2第一次查询这一次不一致,还有另一个极端场景会存在数据不一致。请求1更新数据节点缓存刚好失效了,另一个请求2刚好这时读取缓存没有进而读了数据库旧值,如下图所示:
在这里插入图片描述
这个极端场景需要满足缓存更好失效,而且请求2读取数据库及回写缓存耗时较请求1更新数据库更长,发生的概率非常小,可以忽略,所以相比较而言,方案5是最推荐的处理策略。

通过以上几种处理方案的分析,可以看到不管哪种方案都存在一定的问题,在满足实时性的条件下,尽量保证不一致出现的概率更低,或者不一致持续的时间非常短暂,避免长期不一致。非要满足强一致性可能就需要考虑使用锁的方案了。

总的来说,针对缓存同步更推荐的方式是,缓存中的数据不由数据更新操作主动触发,统一在需要使用的时候按需加载,数据更新后及时删除缓存中的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/80141.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决git reset --soft HEAD^撤销commit时报错

今天在使用git回退功能的时候,遇到以下错误: 解决git reset --soft HEAD^撤销commit时报错 问题: 在进行完commit后,想要撤销该commit,于是使用了git reset --soft HEAD^命令,但是出现如下报错&#xff1…

科大讯飞星火模型申请与chatgpt 3.5模型以及new bing的对比

科大讯飞星火模型 申请科大讯飞星火认知大模型账号科大讯飞星火认知大模型使用1.界面介绍2. 在编程能力上与chatgpt 3.5对比科大讯飞星火模型chatgpt 3.5模型 3. 在图片生成能力上与new bing对比 总结 申请科大讯飞星火认知大模型账号 注册网址: 科大讯飞星火认知大…

ansible入门

ansible入门 一.ansible 背景介绍 Ansible 是一个广受欢迎的 IT 自动化系统。可以用来处理配置管理、应用自动化部署、云资源配给、网络 自动化和多借点部署等任务。其也可以使得复杂的变更如带负载均衡的零停机滚动更新更加容易。Ansible.com 1.1 自动化运维概念 1.1.1 运维…

python+django+mysql项目实践五(信息搜索)

python项目实践 环境说明: Pycharm 开发环境 Django 前端 MySQL 数据库 Navicat 数据库管理 信息搜素 输入内容进行搜索,内容有文本类和时间类 文本类需要模糊搜索,包含即检索 时间类需要选取时间范围内的内容 views 利用Q完成对指定内容的检索 检索后按检索内容更新…

RabbitMq-发布确认高级(避坑指南版)

在初学rabbitMq的时候,伙伴们肯定已经接触到了“发布确认”的概念,但是到了后期学习中,会接触到“springboot”中使用“发布确认”高级的概念。后者主要是解决什么问题呢?或者是什么样的场景引出这样的概念呢? 在生产环…

postgresql 分组

postgresql 数据汇总 分组汇总聚合函数注意 总结 分组统计总结 高级分组总结 分组汇总 聚合函数 聚合函数(aggregate function)针对一组数据行进行运算,并且返回单个结果。PostgreSQL 支持以下常见的聚合函数: • AVG - 计算一…

SpringCloud实用篇7——深入elasticsearch

目录 1 数据聚合1.1 聚合的种类1.2 DSL实现聚合1.2.1 Bucket聚合语法1.2.2 聚合结果排序1.2.3 限定聚合范围1.2.4 Metric聚合语法1.2.5.小结 1.3 RestAPI实现聚合1.3.1 API语法1.3.2 业务需求1.3.3 业务实现 2 自动补全2.1 拼音分词器2.2 自定义分词器2.3 自动补全查询2.4 实现…

C++ STL关联式容器(详解)

STL关联式容器 C STL关联式容器是什么? 在《C STL容器》一节中讲到,C 容器大致分为 2 类,即序列式容器和关联式容器。其中,序列式容器(包括 array、vector、list、deque 和 forward_list)已经在前面章节中…

Golang使用MinIO

最近在使用Golang做了一个网盘项目(学习),文件存储一直保存在本地(各厂商提供的oss贵),所以就在思考怎么来处理这些文件,类似的方案很对hdfs、fastdfs,但这其中MinIO是最近几年比较火…

【Django】Task1安装python环境及运行项目

【Django】Task1安装python环境及运行项目 写在最前 8月份Datawhale组队学习,在这个群除我佬的时代,写一下blog记录学习过程。 参考资源: 学习项目github:https://github.com/Joe-2002/sweettalk-django4.2 队长博客&#xff1a…

windows权限维持—SSPHOOKDSRMSIDhistorySkeletonKey

windows权限维持—SSP&HOOK&DSRM&SIDhistory&SkeletonKey 1. 权限维持介绍1.1. 其他 2. 基于验证DLL加载—SPP2.1. 操作演示—临时生效2.1.1. 执行命令2.1.2. 切换用户 2.2. 操作演示—永久生效2.2.1. 上传文件2.2.2. 执行命令2.2.3. 重启生效 2.3. 总结 3. 基…

k8s的pv和pvc创建

//NFS使用PV和PVC 1、配置nfs存储 2、定义PV 实现 下图的pv和pvc测试 pv的定义 这里定义5个PV,并且定义挂载的路径以及访问模式,还有PV划分的大小 vim /pv.yamlapiVersion: v1 kind: PersistentVolume metadata:name: pv001 spec:capacity:storage: …

私密数据采集:隧道爬虫IP技术的保密性能力探究

作为一名专业的爬虫程序员,今天要和大家分享一个关键的技术,它能够为私密数据采集提供保密性能力——隧道爬虫IP技术。如果你在进行敏感数据采集任务时需要保护数据的私密性,那么这项技术将是你的守护神。 在进行私密数据采集任务时&#xff…

【制作npm包4】api-extractor 学习

制作npm包目录 本文是系列文章, 作者一个橙子pro,本系列文章大纲如下。转载或者商业修改必须注明文章出处 一、申请npm账号、个人包和组织包区别 二、了解 package.json 相关配置 三、 了解 tsconfig.json 相关配置 四、 api-extractor 学习 五、npm包…

Fluent-MyBatis

Fluent-MyBatis Fluent-MyBatis 简介 何为 Fluent Mybatis? Fluent Mybatis, 是一款 Mybatis 语法增强框架, 综合了 Mybatis Plus, Dynamic SQL, JPA 等框架特性和优点 Fluent-MyBatis 开源地址 Fluent-MyBatis 原理 Fluent-MyBatis 原理是利用 annotation pro…

【IMX6ULL驱动开发学习】08.马达驱动实战:驱动编写、手动注册平台设备和设备树添加节点信息

目录 一、使用设备树 1.1 修改设备树流程 二、手动创建平台设备 三、总结(附驱动程序) 前情提要:​​​​​​​【IMX6ULL驱动开发学习】07.驱动程序分离的思想之平台总线设备驱动模型和设备树_阿龙还在写代码的博客-CSDN博客 手动注册…

爬虫逆向实战(五)--猿人学第三题

一、数据接口分析 主页地址:猿人学第三题 1、抓包 通过抓包可以发现数据接口是api/match/3 2、判断是否有加密参数 请求参数是否加密? 无请求头是否加密? 无响应是否加密? 无cookie是否加密? 无 二、发送请求 …

什么是闭包(closure)?为什么它在JavaScript中很有用?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 闭包(Closure)是什么?⭐ 闭包的用处⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&…

基于安防监控EasyCVR视频汇聚融合技术的运输管理系统的分析

一、项目背景 近年来,随着物流行业迅速发展,物流运输费用高、运输过程不透明、货损货差率高、供应链协同能力差等问题不断涌现,严重影响了物流作业效率,市场对于运输管理数字化需求愈发迫切。当前运输行业存在的难题如下&#xf…

架构师必备--高可用高性能分布式数据库Tidb安装部署实践

本文针对分布式、高可用的tidb数据库,从搭建实际生产环境的集群服务,介绍下tidb的安装流程、安装前的环境检测和系统优化、服务访问等方面介绍下具体的流程,希望对大家熟悉和了解tidb数据库有所帮助,减少不必要的弯路。 1.概述 …