Redis延时双删

news2025/1/21 1:35:17

1.为什么缓存和MySQL数据没有保持一致性?

数据一致性是什么意思,“一致性”包含如下情况:

  • 若缓存中有数据,则缓存的数据值需要和DB值相同
  • 若缓存无数据,则DB值必须是最新值

不符合这两种情况的,都属于缓存和DB数据不一致。
不过,当缓存的读写模式不同时,缓存数据不一致的发生情况不一样,应对方法也有所不同。
先按照缓存读写模式,来分别了解下不同模式下的缓存不一致情况。根据是否接收写请求,可以把缓存分成读写缓存和只读缓存。

对于读写缓存,若要对数据进行增删改,就需要在缓存中进行,同时还要根据采取的写回策略,决定是否同步写回DB。

同步直写策略:写缓存时,也同步写数据库,缓存和数据库中的数据一致;
异步写回策略:写缓存时不同步写数据库,等到数据从缓存中淘汰时,再写回数据库。使用这种策略时,如果数据还没有写回数据库,缓存就发生了故障,那么,此时,数据库就没有最新的数据了。
所以,对于读写缓存来说,要想保证缓存和数据库中的数据一致,就要采用同步直写策略。不过,需要注意的是,如果采用这种策略,就需要同时更新缓存和数据库。所以,我们要在业务应用中使用事务机制,来保证缓存和数据库的更新具有原子性,也就是说,两者要不一起更新,要不都不更新,返回错误信息,进行重试。否则,我们就无法实现同步直写。

当然如果对数据的一致性要求没有那么高,可以使用异步写回策略。

对于只读缓存来说,如果有数据新增,会直接写入数据库;而有数据删改时,就需要把只读缓存中的数据标记为无效。这样一来,应用后续再访问这些增删改的数据时,因为缓存中没有相应的数据,就会发生缓存缺失。此时,应用再从数据库中把数据读入缓存,这样后续再访问数据时,就能够直接从缓存中读取了。

1.新增数据

如果是新增数据,数据会直接写到数据库中,不用对缓存做任何操作,此时,缓存中本身就没有新增数据,而数据库中是最新值,这种情况符合我们刚刚所说的一致性的第2种情况,所以,此时,缓存和数据库的数据是一致的。

2.删改数据

如果发生删改操作,应用既要更新数据库,也要在缓存中删除数据。这两个操作如果无法保证原子性,也就是说,要不都完成,要不都没完成,此时,就会出现数据不一致问题了。

假设应用先删除缓存,再更新数据库,如果缓存删除成功,但是数据库更新失败,那么,应用再访问数据时,缓存中没有数据,就会发生缓存缺失。然后,应用再访问数据库,但是数据库中的值为旧值,应用就访问到旧值了。

2.为什么删除缓存而不是更新?

如果是更新,存在分布式事务问题,可能出现修改了缓存,数据库修改失败的情况。只是删除缓存的话,就算数据库修改失败,下次查询会直接取数据库的数据,也不会出现脏数据。

3.延时双删是什么?

就是在增删改某实体类的时候,要对该实体类的缓存进行清空,清空的位置在数据库操作方法的前后。

4.为什么不能采用先删或者后删策略?

先删流程:

 后删流程:

 先删和后删都不能保证数据的一致性,所以采用延时双删的策略。

4.为什么是延时?

双删依然存在旧缓存的情况,延时是确保 修改数据库->清空缓存前,其他事务的更改缓存操作已经执行完。

 

5.为什么要延迟双删,来保证缓存一致性

  • 在修改数据库数据前,需要先删除一次redis:此时是为了保证在数据库数据修改和redis数据被删除的间隔时间内,如有命中,保证此数据也不存在redis中。如果没有这一次删除,当数据库数据已经被修改了,但是还是可以从redis中读出旧数据,导致数据不一致。

  • 第二次删除则是在修改数据库数据后,此时需要再次删除redis中对应数据一次,这一次是为了删除 第一次redis删除和数据库数据修改之间,如果有请求,那么旧数据又会重新缓存到redis中,然而数据在数据库中在接下来就会被修改,如果没有这一次删除,redis中则会存在数据库中旧的数据。

  • 那么第二次为什么需要在数据库修改后延迟一定时间再删除redis呢?

  • 为了等待之前的一次读取数据库,并等待其数据写入到缓存,最后删除这次脏数据,所以是一次数据从数据库中发到服务器+缓存写入的时间

但是延迟双删,所延迟的时间非常的难以确定,所以并不推荐延迟双删

根据综合考虑,即使先修改数据库,在删除缓存,有一定的时间会导致读取到旧数据,这通常是可以被忍受的。
只要及时将缓存删除,其他线程就可以读取到最新的值。

同时为了保证缓存一定会被删除,可以采用mq,来保证缓存会被删除

如果在mq中消息没有被重复消费,还会交由给其他消费者消费(将缓存删除)

6.解决方案

  1. 更新数据库数据
  2. 数据库会将操作信息写入binlog日志当中
  3. 订阅程序提取出所需要的数据以及key
  4. 另起一段非业务代码,获得该信息
  5. 尝试删除缓存操作,发现删除失败
  6. 将这些信息发送至消息队列
  7. 重新从消息队列中获得该数据,重试操作。

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

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

相关文章

【OJ比赛日历】快周末了,不来一场比赛吗? #06.10-06.16 #12场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…)比赛。本账号会推送最新的比赛消息,欢迎关注! 以下信息仅供参考,以比赛官网为准 目录 2023-06-10(周六) #4场比赛2023-06-11…

实验五 标准ACL的配置【网络安全】

实验五 标准ACL的配置【网络安全】 前言推荐实验五 标准ACL的配置问题方案步骤 最后 前言 2023-6-8 18:54:22 以下内容源自《【网络安全】》 仅供学习交流使用 推荐 配置标准ACL 实验五 标准ACL的配置 问题 络调通后,保证网络是通畅的。同时也很可能出现未经…

软件测试与打螺丝

单元测试中的FIRST代表下面五组英文单词对应的原则: FastIsolated / IndependentRepeatableSelf-validatingTimely / Thorough 软件开发中,往往会因为我们没有注意到的逻辑或难以理解的代码,而引进Bug来。 怎么尽早地发现Bug,…

【springCloud-2】Ribbon负载均衡

负载均衡,一般分为服务端负载均衡和客户端负载均衡。 服务端:如Nginx,F5等,请求到达服务器后进行负载均衡。 客户端:客户端获取到服务端的列表,自己经过一定的计算后选择某一台访问。 ribbon实现的就是客…

Monica: 您的又一个免费ChatGPT 4.0

最近 ChatGPT 又开始封号了,主要原因如下: 违反使用条款:如果用户违反了平台或应用的使用条款,例如发布违法、恶意或滥用行为的内容,侵犯他人的权利,或者从事垃圾信息传播等,管理员可能会采取封…

多方合作时,系统间的交互是怎么做的?

大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。 以下是正文! 文章背景 我们最近做了很多…

【资料分享】ESD基本概念及ESD产生来源详解

CMOS工艺集成电路制造技术已经进入纳米时代,随着特征尺寸的降低,ESD (Electro-Static Discharge,静电放电)问题越来越成为集成电路中最主要的可靠性问题。 ESD基本概念 ESD定义:ESD(Electro-Static disc…

垄断与市场力量

五力竞争分析模型 供应商的判断能力购买者的判断能力新进入者的威胁现有的竞争对手产品和服务的替代品的压力产品和服务的互补品 政府决策价值定位 服务哪些客户?满足这些客户的哪些需求?收取什么价格?垄断企业的经营 竞争企业是价格接受者,而垄断企业是价格制定者。 市场…

PURE:A Frustratingly Easy Approach for Entity and Relation Extraction

原文链接: https://aclanthology.org/2021.naacl-main.5.pdf ACL 2021 介绍 对于命名实体识别和关系提取,最近的研究要么在这两个任务上使用一个预训练结构,要么通过共享表征来进行多任务学习。作者认为实体模型和关系模型在上下文表征中学到…

kotlin的abstract抽象类与interface接口建模按钮android点击事件处理

kotlin的abstract抽象类与interface接口建模按钮android点击事件处理 例如: abstract class View {private var listener: OnClickListener? nullprivate var enabled: Boolean falseconstructor() {println("view constructor")}fun setClickListen…

用法详解!postman接口自动化如何进行环境变量

目录 前言: 1.设置环境变量 2.设置全局变量 3.检查response body中是否包含某个string 4.检测JSON中的某个值是否等于预期的值 5.转换XML body为JSON对象 6.检查response body是否与某个string相等 7.测试response Headers中的某个元素是否存在(如:Content-…

自然语言处理: N-Gram实战

自然语言处理: 第一章N-Gram 一. 理论 定义: 语言模型在wiki的定义是统计式的语言模型是一个几率分布,给定一个长度为 m 的字词所组成的字串 W1 , W2 , ,Wn ,派几率的字符串P(S) P(W1 , W2 , ,Wn , )而其…

web audio音效播放器/音乐播放器

这是一个基于Web Audio API、HTML和CSS构建的高级网页音频播放器。它允许用户播放音频文件、控制播放、可视化音频,并应用音频效果和过滤器。 Github仓库: https://github.com/sonichen/Web-Based-Audio-Player 希望大家多多star 环境 操作系统&#…

Android逆向解析加壳与脱壳技术

加壳 加壳是指在 APK 文件中插入额外的代码或数据,使得原始代码难以被分析和反编译。通常加壳是为了保护软件的知识产权或者防止逆向工程。下面是 Android 加壳的一般流程: 选择加壳工具:选择合适的加壳工具进行加壳,比如市面上…

【SpringCloud-1】注册中心-Eureka

springcloud微服务,相对于dubbo这种SOA架构,提供了一站式的全套解决方案,什么意思呢?就是说springcloud不需要依赖其他组件,自己提供了全套的 常规项目需要使用的技术和解决问题的方案。 比如dubbo需要依赖zk作为注册…

一文读懂二叉树

大家好,我是三叔,很高兴这期又和大家见面了,一个奋斗在互联网的打工人。 什么是二叉树 二叉树是一种由节点(Node)组成的数据结构,每个节点最多有两个子节点。它具有良好的层次结构,便于搜索和…

chatgpt赋能python:Python如何将IP地址转换为整数

Python如何将IP地址转换为整数 在计算机网络中,IP地址是一个包含32位的二进制数字,通常由四个8位二进制数字(即“点分十进制”)表示。但在某些情况下,需要将IP地址转换为整数,例如在网络编程中检查网络连接…

C语言:编写代码,演示多个字符从两端移动,向中间汇聚

题目: 给出第一个字符串,如:"welcome to school!!!!!", 设置第二个字符串:"######################", 两字符串字符数相等。 从第二个字符串两端开始移动,向中间汇聚&#…

Python 中判定整数

直接数值判定,表达式判定。 (本笔记适合学会 Python 基本数据类型,可以“融会贯通”的 coder 翻阅) 【学习的细节是欢悦的历程】 Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》&#…

IGP协议对SR-MPLS的扩展

目录 OSPF对于SR-MPLS的扩展 OSPF对邻接SID做了细分 10类LSA定义的TLV类型 10类LSA定义的TLV的报文格式 ISIS对SR-MPLS的扩展 ISIS对邻接SID做了细分 ISIS定义的Sub-TLV的类型 ISIS定义的Sub-TLV的报文格式 OSPF对于SR-MPLS的扩展 OSPF为了支持SR-MPLS通过新…