如何保证Redis的缓存和数据库中的数据的一致性?

news2024/11/24 15:54:21

Redis的缓存如何和数据库中的数据保持一致性?

我们都知道,Redis是一个基于内存的键值存储系统,数据完全存放在内存中,这使得它的读写速度远超传统的硬盘存储数据库。对于高访问频率、低修改率的数据,通过将它们缓存在Redis中,应用可以快速地从内存中获取数据,能够大量减少数据库的查询次数,特别是在高并发场景下,有效避免了数据库可能成为整个系统的瓶颈问题。

🍭 但是在实际开发情景中,我们如何才能保证Redis缓存中的数据和数据库中数据的一致性呢?

什么情况会出现数据的不一致?

MySQL和Redis的操作包括读操作和写操作两种,那么有哪些情况是会导致二者数据不一致的?我们先从读和写的操作流程看起~

使用Redis读取数据的场景

在这里插入图片描述
🔆使用Redis读取数据的场景

  • 客户端发起一个查询数据的接口;
  • 向Redis中查询是否存在该条数据
    • 如果存在则直接返回;
    • 不存在则向数据库中查询,再将数据库中的数据保存在Redis中,然后设置一个过期时间,之后再返回客户端。

💡 设置过期时间的主要作用就是为了保证一些冷数据过期自动淘汰,不至于一直存在Redis中占用空间

使用Redis写数据的场景

🔆对数据进行修改是分为两个步骤:

  • 修改数据库数据
  • 修改/删除Redis缓存

为什么不推荐更新缓存而是直接删除?

删除逻辑非常简单,只需要在下一个线程的时候查询Redis,查询不到再从数据库中加载即可,其副作用只是增加了一次chache miss;而更新缓存的成本更高,因为我们写入数据库的值,很多情况下并不是直接写入缓存的,而是要经过一系列复杂的计算再写入缓存。那么每次写入数据库后,都要再次计算写入缓存的值,无疑是浪费性能,显然直接删除缓存更为合适,推荐直接删除。

🍭那么接下来的问题就是先操作缓存还是先操作数据库了

先操作缓存

在这里插入图片描述

🔆先操作缓存即先将缓存清空,再对数据库数据进行修改

  • 线程一进行删除Redis缓存和修改数据库数据操作,线程二进行查询数据操作
  • 线程一将Redis缓存清空之后发生了网络延迟,此时线程二进行缓存读取
  • 线程二在Redis缓存中查询不到数据,向数据库中查询数据并将查询到的数据加载到Redis缓存中,此时Redis缓存中存储的还是原先的老数据
  • 线程一完成数据的修改操作
  • 此时数据库中的数据是修改后的新数据,而Redis缓存中的数据还是更新前的旧数据,此时就发生了Redis缓存和数据库中的数据不一致的情况

💡 如果先操作Redis缓存的话,就可能出现将Redis中的数据删除之后旧数据又被放入其中去,如果后期再有查询操作,那么在Redis缓存中查询到的数据就会全部是旧的数据,产生了缓存脏读,直到数据到了过期时间被清除掉,如果没有设置过期时间该数据就永远都是脏数据,不能保证Redis和数据库的一致性

先操作数据库

那我们先操作数据库呢?还会有这种问题的发生吗?
在这里插入图片描述

🔆先进行数据库操作流程

  • 线程一进行删除Redis缓存和修改数据库数据操作,线程二进行查询数据操作
  • 线程一首先对数据库中的数据进行修改
  • 在此期间如果出现了另外一个线程来查询数据,就会直接从Redis中读取旧数据返回
  • 线程一操作完数据库后对Redis缓存进行延迟删除
  • 接下来的查询操作在Redis中查询不到数据,会向数据库中查询,并将查询到的数据放入Redis缓存中,此时Redis和数据库中的数据都是修改后的新数据

💡 先删数据库再删缓存,在多线程的情况下,当一个线程删除数据库,另一个线程读取缓存数据,读到的是未修改的Redis缓存中的旧数据,当先前一个线程删除完数据库后就会更新缓存,此时Redis和数据库中的数据就可以一致了,只会产生一次脏读

如何保证数据的一致性

🍭此时我们可以看到,在只读场景中是不会出现数据不一致的情况的,只有在并发的写操作中才会出现。问题已经很清楚了,那么如何解决呢?

强一致性和弱一致性

🔆首先我们先来了解两个概念:强一致性和弱一致性:

  • 强一致性:任何一次读都能读到某个数据的最近一次写的数据;
  • 弱一致性:数据更新后,如果能容忍后续的访问,只能访问到部分或全部访问不到;

延时双删策略

如果我们先操作Redis再操作数据库的话,就会出现我们上面所说到的脏读的问题,要解决这个问题,我们可以使用延迟双删的策略:在更新MySQL之后,等待一个短时间(例如几秒)再尝试第二次删除,防止在这段时间内有请求重建缓存而造成数据不一致。

基于消息队列

使用消息队列(如RabbitMQ、Kafka等)异步处理数据更新,更新MySQL的同时将更新事件发送到队列,消费者收到消息后负责更新Redis缓存。

订阅MySQL binlog同步

Redis可以订阅MySQL的binlog日志,拿MySQL举例,当一条数据发生变更时,MySQL就会产生一条变更日志,我们可以订阅这个日志,拿到具体操作的数据,然后再根据这条数据去删除对应的缓存。

删除重试机制

使用删除重试机制,保证删除缓存成功。比如重试三次,三次都失败则记录日志到数据库并发送警告让人工介入。在高并发的场景下,重试最好使用异步方式,比如发送消息到mq中间件,实现异步解耦。

🏮以上的这些方法最多只能实现弱一致性🏮,也就是不能保证更新后每次读取到的数据都是最新数据,如果我们想要保证每次查询到的数据都是新的数据的话,即保证数据的强一致性,那就必须要保证他们的操作是原子性的,那么只能加一把锁了。但是加锁的话是会影响到系统的吞吐量,而我们使用Redis就是为了提高性能,如果为了保证数据的强一致性而加一把锁,那么就得不偿失了。

总结

  • 数据不一致的情况在只读场景中是不会出现的,只有在并发的写操作中才会出现;
  • 相对于直接删除Redis缓存来讲,修改缓存的成本更高,因此更加推荐修改数据库后直接删除Redis缓存,在下一次查询操作时再向数据库中拿到数据保存在Redis中;
  • 先操作Redis的话为了保证和数据库数据的最终一致性,需要进行延时双删的操作,即对Redis缓存进行两次删除,相比于先操作MySQL来说多进行一次删除Redis的操作;
  • 无论是先操作数据库还是先操作缓存,都会出现脏读的情况,因为redis和数据库不是原子性的,要想保证其原子性那么只有加锁,但是加锁的话又会影响性能;
  • Redis删除失败要进行重删操作

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4.6 offset指令,jmp short指令,far,dword ptr各种跳转指令

4.6 offset指令,jmp short指令,far,dword ptr各种跳转指令 可以修改IP,或同时修改CS和IP的指令统称为转移指令。概括的讲,转移指令就是可以控制CPU执行内存中某处代码的指令 1. 转移指令 1.1 8086CPU的转移行为有以…

城市治理/县域治理方案:构建基于AI视频能力的“一张网”,助力新型城市发展

TSINGSEE青犀AI算法中台是一款平台型产品,专注于提供各行业中小场景部署解决方案。平台具备接入广、性能强、支持跨平台、芯片国产化等特点,可提供丰富的视图接入能力和智能分析能力。 平台采用了多项IT高新技术,包括视频编解码技术、嵌入式…

宁盾身份域管与Coremail邮件系统完成兼容互认证,持续深化信创布局

在信创国产化改造的背景下,企业邮箱的替换是许多党政、央国企、金融、制造企业面临的重要任务。为了满足企业对国产邮箱、OA等其他应用、终端实现统一身份认证,宁盾国产化身份域管与 Coremail XT 安全增强电子邮件系统 V5.0、V6.0 完成了产品兼容互认证&…

从redux的基本概念渐进式理解redux/toolkit的用法

概念 Redux toolkit是帮助提高redux开发效率的一个库 React-redux 是将React和Redux toolkit绑定在一起的一个库 action 是一个对象,里面有一个type属性 action creator是一个函数,这个函数可以返回上面的action对象。 reducer 是一个函数,接受两个参数(initilastate, acti…

【Vue3源码学习】— CH2.8 Vue 3 响应式系统小结

Vue 3 响应式系统小结 1.核心概念1.1 Proxy和Reflect1.2 响应式API1.3 依赖收集与更新触发1.4 触发更新(Triggering Updates):1.5 副作用函数(Effect)1.6 计算属性和观察者1.7 EffectScope1.8 性能优化: 2.…

基于深度学习的机场航拍小目标检测系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)

摘要:在本博客中介绍了基于YOLOv8/v7/v6/v5的机场航拍小目标检测系统。该系统的核心技术是采用YOLOv8,并整合了YOLOv7、YOLOv6、YOLOv5算法,从而进行性能指标的综合对比。我们详细介绍了国内外在机场航拍小目标检测领域的研究现状、数据集处理…

多类别分类器(Machine Learning研习十八)

多类别分类器 二元分类器可以区分两个类别,而多类别分类器(也称为多叉分类器)可以区分两个以上的类别。 一些 Scikit-Learn 分类器(如 LogisticRegression、RandomForestClassifier 和 GaussianNB)能够原生处理多个类…

硬件了解 笔记 2

CPU 内存控制器:负责读写数据 代理系统和平台IO:与主板上的芯片组通信,并管理PC中其他组件之间的数据流 主板:巨大的印刷电路板 Chipset:芯片组,位于散热器下方,直接连接到CPU的系统代理部分 …

HTTP/1.1、HTTP/2、HTTP/3 演变(计算机网络)

HTTP/1.1 相比 HTTP/1.0 提高了什么性能? HTTP/1.1 相比 HTTP/1.0 性能上的改进: 使用长连接改善了短连接造成的性能开销。支持管道网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去&#xff0c…

UniApp 应用发布到苹果商店指南

🚀 想要让你的 UniApp 应用在苹果商店亮相吗?别着急,让我来带你一步步完成这个重要的任务吧!在这篇博客中,我将详细介绍如何将 UniApp 应用顺利发布到苹果商店,让你的应用跻身于苹果生态之中。 引言 &…

MySQL 数据学习笔记速查表(视图、存储过程、事务)

文章目录 十三、视图1、视图是什么?2、视图的特性?3、视图的作用?4、视图的用途?5、视图的使用?1、基本语法2、创建视图3、调用视图4、视图练习(1) 利用试图简化复杂的联结(2) 利用视图重新格式化检索出的数据(3) 利用…

【flutter封装图片/视频选择控件】

引入库 wechat_assets_picker: ^6.0.5 、video_player: ^2.5.1 # 视频播放、 flutter_screenutil: ^5.7.0 import dart:async; import dart:io; import package:generated/l10n.dart; import package:jade/configs/PathConfig.dart; import package:jade/customWidget/addImag…

gateway应用(1)

1 简介 简单理解---业务服务的统一入口,方便实现,服务路由,安全,限流,过滤,黑白名单,证书加密解密,服务降级/熔断,灰度,等等 2 介绍 Predicate&#xff08…

Raven:一款功能强大的CICD安全分析工具

关于Raven Raven是一款功能强大的CI/CD安全分析工具,该工具旨在帮助广大研究人员对GitHub Actions CI工作流执行大规模安全扫描,并将发现的数据解析并存储到Neo4j数据库中。 Raven,全称为Risk Analysis and Vulnerability Enumeration for C…

Linux操作系统基础入门​

1、操作系统简介​ a. DOS 和 Windows NT​ DOS是一个与Unix完全不相干的操作系统,这一点可以从DOS使用反斜杠来表示文件目录分隔符上 看出来。随着IBM个人PC的流行,微软DOS操作系统在个人电脑上流行起来。Windows 95, Windows 98, 和 Windows ME底层都…

Databend 集成 PRQL:现代数据处理的一小步

PRQL,读作 “Prequel”,是一种与 SQL 并肩的查询语言,它的独到之处在于采用了管道式的语法,在查询关系数据库时显得更加直观和高效。 Databend 拥抱 PRQL 在 v1.2.380-nightly 版本中,得益于社区贡献者 ncuwaln 提交…

《PDVC》论文笔记

PS:模型代码解释清明后出 原文链接: [2108.07781v1] End-to-End Dense Video Captioning with Parallel Decoding (arxiv.org) 原文笔记: What: End-to-End Dense Video Captioning with Parallel Decoding 并行解码的端到端…

法律行业案例法模型出现,OPenAI公布与法律AI公司Harvey合作案例

Harvey与OpenAl合作,为法律专业人士构建了一个定制训练的案例法模型。该模型是具有复杂推理广泛领域知识以及超越单一模型调用能力的任务的AI系统,如起草法律文件、回答复杂诉讼场景问题以及识别数百份合同之间的重大差异。 Harvey公司由具有反垄断和证…

uniapp,文字超出几行显示省略号...,展开显示更多

效果图&#xff1a; 代码&#xff1a; <template><view class"text-container"><text class"text-content" click"showDetail">{{ text }}</text><text v-if"showMore" class"view-detail" cli…

ModusToolbox 实战入门- XMC GPIO应用篇

导读 ModusToolbox™ 软体&#xff1a;MCU 开发的利器 ModusToolbox™ 软体是一组支援 MCU 周边配置和应用的工具和发展。这些工具使您能够将我们的 MCU 整合到您现有的开发方法中。 ModusToolbox™ 软体的优点 提供完整的 MCU 周边配置和应用工具可整合到现有的开发方法中…