REDIS21_缓存双写一致方案、先更新数据库再删除缓存

2023/9/30 17:26:18

文章目录

  • ①. 什么是缓存双写一致
  • ②. 先更新数据库,再更新缓存
  • ③. 先删除缓存,再更新数据库
  • ④. 先更新数据库,再删除缓存

①. 什么是缓存双写一致

  • ①. 缓存双写一致性,谈谈你的理解
  1. 如果redis中有数据,需要和数据库中的值相同
  2. 如果redis中无数据,数据库中的值要是最新值
  • ②. 什么时候同步直写?
    小数据,某条、某一小戳热点数据,要求立刻变更,可以前台服务降价一下,后台马上同步直写

  • ③. 什么时候异步缓写?

  1. 正常业务,马上更新mysql,可以在业务上容许出现1个小时后redis起效
  2. 出现异常后,不得不将失败的动作重新修补,不得不借助Kafka或者RabbitMQ等消息中间件,实现解耦后重试重写

②. 先更新数据库,再更新缓存

  • ①. 先更新mysql的某商品的库存,当前商品的库存是100,更新为99个

  • ②. 先更新mysql修改为99成功,然后更新redis

  • ③. 此时假设异常出现,更新redis失败了,这导致mysql里面的库存是99而redis里面的还是100

  • ④. 上述发生,会让数据库里面和缓存redis里面数据不一致,读到脏数据

③. 先删除缓存,再更新数据库

  • ①. A线程先成功删除了redis里面的数据,然后去更新mysql,此时mysql正在更新中,还没有结束。(比如网络延时)B突然出现要来读取缓存数据

  • ②. 此时redis里面的数据是空的,B线程来读取,先去读redis里数据(已经被A线程delete掉了),此处出来2个问题:

  1. B从mysql获得了旧值:B线程发现redis里没有(缓存缺失)马上去mysql里面读取,从数据库里面读取来的是旧值
  2. B会把获得的旧值写回redis:获得旧值数据后返回前台并回写进redis(刚被A线程删除的旧数据有极大可能又被写回了)
  • ③. A线程更新完mysql,发现redis里面的缓存是脏数据

  • ④. 总结流程

  1. 请求A进行写操作,删除缓存后,工作正在进行中…A还么有彻底更新完
  2. 请求B开工,查询redis发现缓存不存在
  3. 请求B继续,去数据库查询得到了myslq中的旧值
  4. 请求B将旧值写入redis缓存
  5. 请求B将旧值写入redis缓存
    在这里插入图片描述
  • ⑤. 采用延时双删策略:
    加上sleep的这段时间,就是为了让线程B能够先从数据库读取数据,再把缺失的数据写入缓存,然后,线程A再进行删除。所以,线程A Sleep的时间,就需要大于现场B读取数据再写入缓存的时间。这样一来,其他线程读取数据时,会发生缓存缺失,所以会从数据库中读取最新值。因为这个方案会在第一次删除缓存值后,延迟一段时间再去进行删除,所以我们也把它叫做"延迟双删"
    在这里插入图片描述
  • ⑥. 这个删除该休眠多久呢?这个时间怎么确定呢?
  1. 在业务程序运行的时候,统计下线程读数据和写缓存的操作时间,自行评估自己的项目的读数据业务逻辑的耗时,以此为基础来进行估算。然后写数据的休眠时间则在读数据业务逻辑的耗时基础上加百毫秒即可
  2. 这么做的目的,就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据
  • ⑦. 这种同步淘汰策略,吞吐量降低怎么办?异步删除
    在这里插入图片描述

④. 先更新数据库,再删除缓存

  • ①. 异常原因:假如缓存删除失败或者来不及,导致请求再次访问redis时缓存命中,读取到的是缓存旧值
    在这里插入图片描述
  • ②. 解决方案
  1. 可以把要删除的缓存值或者是要更新的数据库值暂存到消息队列中(例如使用Kafka/RabbitMQ等)
  2. 当程序没有能够成功地删除缓存值或者是更新数据库值时,可以从消息队列中重新读取这些值,然后再次进行删除或更新
  3. 如果能够成功地删除或更新,我们就要把这些值从消息队列中去除,以免重复操作,此时,我们也可以保证数据库和缓存的数据一致了,否则还需要再次进行重试
  4. 如果重试超过的一定次数后还是没有成功,我们就需要向业务层发送报错信息了,通知运维人员
    在这里插入图片描述
  • ③. 谈谈为什么要引入MQ
  1. 在应用程序将数据更新到数据库后,将更新操作发送到消息队列中,然后再由消息队列异步地触发删除缓存数据的操作
  2. 这样做的好处是,即使在更新数据库后发生异常或者网络延迟等问题,数据更新操作也已经被放到消息队列中,并不会导致缓存数据和数据库数据不一致的问题

http://www.jnnr.cn/a/369224.html

相关文章

MarTech老将如何焕发新生?数据猿直播干货分享

‍数据智能产业创新服务媒体——聚焦数智 改变商业MarTech一直备受关注,然而2022年的MarTech市场却不尽如人意。据最新数据显示,2022年,MarTech行业的融资总额为302.43亿元人民币,与2021年相比下降了31.7%。可见后疫情时代&#…

windows通过浏览器访问noVNC(基于web的远程桌面)

目录 一、什么是VNC 和 noVNC? 二、Windows10安装及配置noVNC 2.0、注释 2.1、下载UltraVNC 2.2、下载Node.js 2.3、下载安装git 2.4、创建一个存放文件的文件夹 2.5、安装ws、optimist、mime-types模块(执行websockify.js文件所需) …

双master节点+keepalived方式部署K8s 1.18.20

相关部署方式也挺多,自己采用双master节点单node节点方式,并且采用keepalived部署1.18.20版本,中间也出现过相关小问题,但都一一处理,记录以给需要的同仁们参考,希望大家都可以一起学习交流!&am…

【Git从入门到精通】分支机制

文章目录简述创建新分支切换分支基本的分支与合并操作基本的分支操作基本的合并操作基本的合并冲突解决远程分支推送跟踪分支拉取删除Git的分支模型是Git的杀手锏特性 简述 首先我们来看一下Git是如何存储数据的。 Git通过一系列的快照的方式来存储数据,当你发起提…

聊聊Java线程是个啥东西-Java多线程(1)

为什么要有线程在这个效率和质量并存的时代,首先, "并发编程" 成为 "刚需".单核 CPU 的发展遇到了瓶颈. 要想提高算力, 就需要多核 CPU. 而并发编程能更充分利用多核 CPU 资源. 有些任务场景需要 "等待 IO", 为了让等待 IO 的时间能够去做一些其…

【iOS】—— 多线程之pthread、NSThread

文章目录1.pthreadpthread简介:pthread使用方法pthread 其他相关方法2.NSThread创建,启动线程线程相关用法线程相关用法线程状态控制方法线程之间的通信NSThread线程安全和线程同步NSThread 非线程安全NSThread 线程安全线程的状态转换NSThread线程属性n…

Java基础知识——8.字符串及其拓展(完整版)

这篇文章我们来详细的讲一下字符串即String及其拓展。前面一篇也讲了,但是讲的很粗浅,这里我们详细的完整的讲一下,力争讲透String。 目录 1.String类 2.字符串常量池 3.总结 3.1 String类初始化后是不可变的(immutable) 3.2 引用变量与…

【新2023Q2押题JAVA】华为OD机试 - 优秀员工统计

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:优秀员工统计 题目 公司某部…

这几种常见的 JVM 调优场景

假定你已经了解了运行时的数据区域和常用的垃圾回收算法,也了解了Hotspot支持的垃圾回收器。 一、cpu占用过高 cpu占用过高要分情况讨论,是不是业务上在搞活动,突然有大批的流量进来,而且活动结束后cpu占用率就下降了&#xff0…

zlmedaikit android编译

Windows 10 64bit Android Studio:Android Studio Electric Eel | 2022.1.1 Patch 2 NDK: android-ndk-r25c 1. 安装jdk 2. 打开http://ping.chinaz.com网站,输入dl.google.com地址,开始ping监测,选择一个时间最短的大陆IP地址&a…

C语言函数:内存函数memcpy()以及实现

C语言函数&#xff1a;内存函数memcpy() 引言&#xff1a; #define _CRT_SECURE_NO_WARNINGS#include <stdlib.h>int main() {int arr1[20] { 1,2,3,4,5,6,7,8,9 };int arr2[20] { 0 };strcpy(arr2, arr1);return 0; } strcpy函数&#xff1a;C语言函数&#xff1a;字…

Mac升级go版本(指定或最新)

升级流程 在Mac中对go版本的升级采用先卸载后安装的过程进行go版本升级&#xff08;或者回退&#xff09;。 卸载 在卸载前&#xff0c;先查看下当前的go版本&#xff1a; go version 删除 go 目录&#xff1a; sudo rm -rf /usr/local/go /usr/local/go/bin/go /etc/path…

CSS面试题

CSS面试题css画三角形&#xff1a;本质就是利用边框bordercss选择器优先级一个div&#xff0c;没有给高度和宽度&#xff0c;怎么水平垂直居中height与line-height的区别css画三角形&#xff1a;本质就是利用边框border 我们首先看一种情况&#xff1a; width:0px; height:0px…

数据库:Redis哨兵及cluster集群部署

一、redis数据库哨兵模式 目录 一、redis数据库哨兵模式 1、什么是哨兵模式 2、哨兵的作用 3、哨兵结构组成 4、哨兵故障转移机制 5、哨兵工作、切换原理 6、哨兵主节点选举原则 7、哨兵模式部署 二、redis数据库cluster集群 1、cluster集群优点、数据存储及同步方式…

【操作系统复习】第3章 处理机调度与死锁 3

死锁&#xff08;Deadlock&#xff09;&#xff1a;指多个进程在运行过程中因争夺资源而造成的一种僵局&#xff0c;当进程处于这种僵持状态时&#xff0c;若无外力作用&#xff0c;这些进程都将永远不能再向前推进。 对资源不加限制地分配可能导致进程间由于竞争资源而相互制约…

【Docker】1、Docker 基础知识随意介绍

文章目录一、什么是 Docker二、为什么要用 Docker 部署三、Ubuntu Docker 安装四、Dockerfile五、镜像5.1 镜像拉取5.2 镜像删除5.3 使用 docker save 将镜像保存成 tar 归档文件5.4 导入使用 docker save 导出的镜像5.5 使用 docker import 从归档文件中创建镜像5.6 将本地镜像…

CNStack 网络插件:hybridnet 的设计与实现

作者&#xff1a; 若禾 CNStack 是阿里云推出的一款开放的一站式企业级云原生技术中台。在异构的混合云基础设施上&#xff0c;对资源进行统一纳管和优化调度&#xff0c;以开放的、云原生的方式为平台及业务系统提供生产可用的产品及组件&#xff0c;帮助用户打造满足大规模、…

【Python小技巧】Anaconda环境下使用Notepad++运行python程序

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、Anaconda、notepad是什么&#xff1f;二、配置过程1. 找到Python.exe2. 编辑运行命令3. 试运行一段代码4. 保存快捷方式总结前言 最近升级了电脑系统&#…

Qt音视频开发27-ffmpeg视频旋转显示

一、前言 用手机或者平板拍摄的视频文件,很可能是旋转的,比如分辨率是1280x720,确是垂直的,相当于分辨率变成了720x1280,如果不做旋转处理的话,那脑袋必须歪着看才行,这样看起来太难受,所以一定要想办法解析到视频的旋转角度,然后根据这个角度重新绘制。在窗体那边也…

《花雕学AI》05:令人惊奇的ChatGPT,一个能够与人类对话的人工智能

今天是周末&#xff0c;4月2日&#xff0c;早上五点就起床了&#xff0c;没有去打羽毛球。 我平时在手机上喜欢看今日头条&#xff0c;了解各种时事新闻&#xff0c;发现今年来频繁出现的单词就是&#xff1a;ChatGPT&#xff0c;通过简单搜索&#xff0c;我逐步接受了这个概念…
最新文章