Redis与DataBase保持数据一致性
文章目录
- 1. 读取数据
- 2. 写数据
- 2.1 先操作缓存
- 2.2 先操作数据库
在我们系统中缓存最常用的策略是:服务端需要同时维系DB和Cache,并且是以DB的结果为准,
Cache-Aside Pattern(缓存分离模式、旁路缓存)。
1. 读取数据

当用户查询数据时,首先先到Redis中进行查询,如果没有命中,则到数据库中进行查询。在数据库中查询到数据后,将数据返回,并且存入到Redis中,设置过期时间,设置过期时间是为了避免长时间未使用的数据一直存放在Redis中,占用内存空间。
2. 写数据
用户在写入数据时,要操作Redis和DataBase。有以下几种操作:
先操作Redis缓存
- 先更新缓存,再更新数据库
- 先删除缓存,再更新数据库
先操作DataBase数据库
- 先更新数据库,再更新缓存
- 先更新数据库,再删除缓存
对于是更新Redis中的数据,还是删除Redis中的数据,其实更推荐是删除Redis中的数据。
因为,如果是选择修改Redis数据,而不是删除,那么如果再修改Redis数据成功后,再去更新数据库中的数据时失败,这样就会导致Redis和DataBase中的数据不一致。再或者如果先成功更新了数据库中的数据,再去更新Redis中的数据时失败了,那么下次查询到Redis中的数据虽然存在,但是为错误数据。
在更新缓存与删除缓存之中,我们确定了是使用删除Redis缓存中的数据。那么剩下的一个问题就是,先更新数据库,还是先删除Redis缓存?
对于这两种情况,我们分别进行讨论。
2.1 先操作缓存

先操作缓存,也就是先将Redis中的数据删除,然后再更新DataBase中的数据。
数据不一致
考虑这种情况下会出现的问题:
- Redis中的数据成功被删除了。
- 在数据被写入数据库之前,此时有线程2存在,线程2读取DataBase中的数据,读取成功后存入了Redis中。
- 线程2从DataBase中读取数据后,线程1的新数据写入DataBase。
- 此时再去读取数据时,因为Redis中数据存在,所以会直接读取Redis中的数据,但是Redis中的数据是旧数据,此时就出现了数据不一致问题。

出现上述这种情况时,该如何解决呢?
(双删)有一种解决方法:
- Redis中的数据成功被删除了
- 在数据被写入数据库之前,此时有线程2存在,线程2读取DataBase中的数据,读取成功后存入了Redis中。
- 线程2从DataBase中读取数据后,线程1的新数据写入DataBase。
- 线程1的新数据写入DataBase后,再次执行将Redis中的数据删除。
- 此时再去读取数据时,因为Redis中数据不存在,所以会到DataBase中查询数据,再将查询到的数据存入Redis中,这样保证了数据的一致性。

但是,这种处理方法,还是存在一种缺陷。如以下情况:
- 线程1更新数据,Redis中的数据成功被删除了。
- 线程2读取数据,先查缓存,缓存中数据不存在,查询数据库,查询到旧数据。
- 线程1删除Redis数据成功后,将新数据写入数据库。
- 线程1将新数据写入数据库后,删除Redis中的缓存数据。
- 线程2将查询到的旧数据返回,并将数据写入到Redis中。
- 此时,Redis中的数据为旧数据,又导致了Redis与数据库中数据不一致的问题。

为了解决上述问题,我们可以将第5步操作进行延迟。在上诉例子中,也就是让线程2先将旧数据存入到Redis中,线程1再去删除Redis中的数据。这种处理方法称为延迟双删。
对于先操作缓存,再操作数据库的情况中,处理数据不一致性问题,我们一般采用延迟双删的方法进行处理。
2.2 先操作数据库

先操作数据库,也就是先更新DataBase中的数据,然后再将Redis中的数据删除。
此时,线程2存在,如果数据再Redis中存在,那么不会出现数据不一致问题。
线程2查询数据,首先查询缓存,数据存在直接返回,只是线程2可能查到的为旧数据,但是这并不影响Redis与DataBase的数据一致性。

除了这种情况外,还有一种情况存在。Redis中不存在被更新的该数据。那么就会出现以下情况:
- 线程2查询数据,先查询Redis中的数据,数据不存在,到数据库中查询数据,查询到旧数据。
- 线程1更新数据库中的数据。
- 线程1更新完数据库中的数据后,执行对Redis中数据的删除操作。
- 线程2将查询到的旧数据存储到Redis中。此时就出现了数据不一致行问题。

对于这种情况,我们对于图中第4步操作还是采用延迟删除进行处理。
但是这种情况下,也会存在一种问题,就是第3步操作,删除缓存失败。针对这种删除缓存失败的情况,我们可以采用删除重试机制进行解决。我们可以引入MQ消息队列。

但是,加入了删除重试后,非业务代码和业务代码耦合度太高了。
我们想解耦的话,就可以采用另一个组件,叫做canal。
canal是阿里的一款开源框架,主要用途是基于MySQL数据库增量日志解析,提供增量数据订阅和消费。
Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端。

相关文章:
Redis与DataBase保持数据一致性
文章目录 1. 读取数据2. 写数据2.1 先操作缓存2.2 先操作数据库 在我们系统中缓存最常用的策略是:服务端需要同时维系DB和Cache,并且是以DB的结果为准, Cache-Aside Pattern(缓存分离模式、旁路缓存)。 1. 读取数据 当…...
解决 MacOS 连接公司 VPN 成功但是不能网络的问题
目录 解决办法2024 Mac mini 爆料 解决办法 操作比较简单,修改配置文件即可(如果没有则需要手动创建)。 sudo vim /etc/ppp/options在此文件下,加入 plugin L2TP.ppp: plugin L2TP.ppp如果文件里有l2tpnoipsec&…...
【Kubernetes】k8s集群之Pod容器资源限制和三种探针
目录 一、Pod容器的资源限制 1.资源限制 2.Pod 和容器的资源请求与限制 3.CPU 资源单位 4.内存资源单位 二、Pod容器的三种探针 1.探针的三种规则 2.Probe支持三种检查方法: 一、Pod容器的资源限制 1.资源限制 当定义 Pod 时可以选择性地为每个容器设定所…...
从古代驿站体系看软件安全管控@安全历史04
在古代,车、马都很慢,信息传递很不顺畅,中央的政令又是如何传达至地方的呢?实际上,很多朝代都有专门的驿站制度,可以保障全国各地的信息传递,对于维护统治和稳定有着关键作用。 若将国家比作一个…...
8.8 哈希表简单 1 Two Sum 141 Linked List Cycle
1 Two Sum class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {//给的target是目标sum 要返回vector<int> res(2,0);是在num中找加数//首先假设每个输入都是由唯一的结果,而且不适用相同的元素两次一共有n*(n-1)种…...
动态规划之——背包DP(完结篇)
文章目录 概要说明分组背包模板例题1思路code模板例题2思路code 有依赖的背包问题模板例题思路code 背包问题求方案数模板例题思路code 背包问题求具体方案模板例题思路code 概要说明 本文讲分组背包、有依赖的背包、 背包问题求方案数以及背包问题求具体方案 入门篇(01背包和…...
Advanced IP Scanner - 网络扫描工具介绍
Advanced IP Scanner 是一款免费、快速且用户友好的网络扫描工具。它能够帮助用户扫描局域网(LAN)中的所有设备,提供详细的设备信息,包括IP地址、MAC地址、设备名称和厂商信息。该工具对IT管理员和普通用户都非常有用,…...
数据库事务的四大特性ACID
数据库事务的四大特性ACID 数据库事务(Transaction)是数据库管理系统(DBMS)执行过程中的一个逻辑单位,由一个或多个SQL语句组成,这些语句作为一个整体一起向系统提交,要么全部执行,…...
ELK架构介绍
一、ELK简介 ELK 是由三个开源软件组成的,分别是:Elasticsearch、Logstash和Kibana,这三个软件各自在日志管理和数据分析领域发挥着重要作用。Elasticsearch提供分布式存储和搜索能力;Logstash负责数据收集和处理,而K…...
Vscode下ESP32工程函数定义无法跳转
1.删除.vscode 2.按下 ctrlshiftp,搜索 ESP-IDF:Add vscode Configuration Folder...
liquibase.exception.LockException: Could not acquire change log lock.
项目场景: 启动应用花了好长时间,最后报出异常. 问题描述 启动应用花了好长时间,最后报出异常. 异常: Caused by: liquibase.exception.LockException: Could not acquire change log lock. Currently locked by LAPTOP-OQ9VB…...
【多线程-从零开始-捌】阻塞队列,消费者生产者模型
什么是阻塞队列 阻塞队里是在普通的队列(先进先出队列)基础上,做出了扩充 线程安全 标准库中原有的队列 Queue 和其子类,默认都是线程不安全的 具有阻塞特性 如果队列为空,进行出队列操作,此时就会出现阻…...
数据结构——栈(Stack)
目录 前言 一、栈的概念 1、栈的基本定义 2、栈的特性 二、栈的基本操作 1.相关操作概念 2.实现方式 (1)顺序栈 (2)链式栈 三、栈的应用 总结 前言 栈(Stack)是一种常见且重要的数据结构,它遵循…...
修改pom.xml为阿里云仓库并且让他生效
一、项目pom.xml添加 <repositories><repository><id>aliyun-central</id><name>Aliyun Maven Central</name><url>https://maven.aliyun.com/repository/central</url></repository><repository><id>aliyu…...
step13:qml/qt程序打包
文章目录 0.文章介绍1.软件发布2.准备打包软件3.双击开始运行打包软件4.点击安装5.参考连接 0.文章介绍 1.软件发布 打包之前需要先发布,参考教程连接 2.准备打包软件 官方下载地址:http://www.jrsoftware.org/isdl.php#stable 下载之后一路点击下一…...
招聘求职小程序
本文来自:ThinkPHPFastAdmin招聘求职小程序 - 源码1688 应用介绍 一款基于ThinkPHPFastAdmin开发的原生微信小程序招聘管理系统。 前端小程序演示: 后台管理网址: https://fastadmin.site100.cn/PbfhegDBAJ.php/index/login 网盘链接&#x…...
10分钟学会docker安装与使用
文章目录 1、docker简介2、docker的基本组成3、docker的安装与配置4、docker的常用命令 1、docker简介 什么是容器? 它是一种虚拟化的方案,是操作系统级别的虚拟化,只能运行相同或相似内核的操作系统,依赖于Linux内核特性&#x…...
vue3、uniapp-vue3模块自动导入
没有使用插件 使用插件,模块自动导入 安装: npm i -D unplugin-auto-importvite.config.js (uniapp没有此文件,在项目根目录下创建) import { defineConfig } from "vite"; import uni from "dcloudio/vite-plugin-uni"; import AutoImport from &qu…...
Ubantu设置国内镜像(阿里云、华为云)
1. 确定系统版本 国内有很多 Ubuntu 的镜像源,包括阿里的、网易的,还有很多教育网的源,比如:清华源、中科大源等。 不同的 ubantu 版本对应的镜像源有所不同,所以需要先查看系统的版本号: lsb_release -a…...
Redis远程字典服务器(3)——常用数据结构和单线程模型
目录 一,常用数据结构 1.0 前言 1.1 string 1.2 hash 1.3 list 1.4 set 1.5 zset 1.6 演示 二,关于单线程模型 2.1 关于Redis的单线程 2.2 Redis为什么快 一,常用数据结构 1.0 前言 Redis是采用键值对的方式来存储数据的&#…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
TJCTF 2025
还以为是天津的。这个比较容易,虽然绕了点弯,可还是把CP AK了,不过我会的别人也会,还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...
基于stm32F10x 系列微控制器的智能电子琴(附完整项目源码、详细接线及讲解视频)
注:文章末尾网盘链接中自取成品使用演示视频、项目源码、项目文档 所用硬件:STM32F103C8T6、无源蜂鸣器、44矩阵键盘、flash存储模块、OLED显示屏、RGB三色灯、面包板、杜邦线、usb转ttl串口 stm32f103c8t6 面包板 …...
计算机系统结构复习-名词解释2
1.定向:在某条指令产生计算结果之前,其他指令并不真正立即需要该计算结果,如果能够将该计算结果从其产生的地方直接送到其他指令中需要它的地方,那么就可以避免停顿。 2.多级存储层次:由若干个采用不同实现技术的存储…...
