Redis 和 Mysql 数据库数据如何保持一致性????

news2024/11/27 14:54:59

1、前言

我们在实际项目中经常会使用到Redis缓存用来缓解数据库压力,但是当更新数据库时,如何保证缓存及数据库一致性,一般我们采用延时双删策略。

目前系统中常用的做法是一个查询接口,先查询Redis,如果不存在则查询数据库,并将结果放入到Redis中。

为什么是删除缓存,而不是更新缓存呢?主要是如果缓存的内容是带有树型结构或者List,Map,那么更新其中一个内容相对较慢。

本文所讲操作,均是按照如果缓存不存在,查询数据库后,再放入Redis。

2、常见更新策略

  • 1 先删缓存,再更新数据库

  • 2 先更新数据库,再删除缓存

  • 3 普通双删

  • 4 延迟双删

3、图解

3.1、先删缓存,再更新数据库

1、线程A删除缓存数据,此时还没更新数据库

2、线程B查询缓存没有数据,查询数据库还是旧数据,放入缓存

3、线程C及其他线程使用旧缓存数据,缓存和数据库不一致

3.2、先更新数据库,再删除缓存

1、线程A更新数据库,此时还没有删除缓存

2、线程B及其他线程此时使用的还是旧缓存数据,和数据库内容不一致

3.3、普通双删

1、线程A先删除缓存,再更新数据库,再删除缓存

2、线程B查询缓存没有数据,在线程A更新数据库之前,查询到旧数据,此时系统时间片切换到线程A执行删除缓存,之后又轮到线程B放入缓存旧数据

3、线程C针对于线程A,查询缓存没有数据,查询到旧数据,放入缓存旧数据

都不能满足缓存和数据一致性。

3.4、延迟双删

1、线程A先删除缓存,之后更新数据库

2、线程B和线程C发现缓存没数据,查询数据库。线程B查询到的是旧数据,线程C查询到的是新数据。之后纷纷放入缓存

3、线程A延时3-5秒(时间一般要大于SQL执行时间+线程切换执行时间100ms足够),再将缓存删除。之后其他线程再查询缓存,发现没数据,再次查询数据库及放入缓存都是新数据

极端情况就是线程D,所以延时双删还是不一定能保证缓存及数据一致。

4、建议

1、在发现缓存没有数据后,在执行查询数据库前,对该Key进行加锁,查询数据库并放入缓存后再解锁,这样可以避免缓存击穿问题,当某个redis数据不存在时,大量线程并发查询数据库。

2、在需要执行双删前,对该Key进行加锁,之后执行删除缓存,更新数据库,放入新数据到缓存,在解锁。保证缓存和数据一致性。

3、加锁的Key都需要设置过期时间,避免因为宕机造成死锁。

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

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

相关文章

esp32中vscode的开发环境

vscode中安装esp32开发环境请参考:CSDN 1、调出esp32的控制面板View ->Command Paletter,或者快捷键(ctrshitp) 调出esp-idf的样例工程 选择ESP-IDF所在的安装路径 选择一个样例工程,作为工程模板 创建的新工程如…

实现ls -l 功能,index,rindex函数的使用

index(); rindex();----------------------------------------------------------------- index第一次遇到字符c&#xff0c;rindex最后一次遇到字符c&#xff0c;返回值都是从那个位置开始往后的字符串地址 #include <stdio.h> #include <sys/types.h> #include &…

MySQL Server 8.3.0 重要变更解析

MySQL Server 8.3.0 Innovation 版本是 MySQL 8.x 系列最后一个创新版本&#xff0c;下个月即将迎来 MySQL 8.4.0 LTS 长期支持版本。 关于发版模型变更&#xff0c;在之前的文章 重磅&#xff01;MySQL 8.1.0 已来&#xff01; 中已有所介绍。 这里补充一点&#xff0c;对于 M…

11-设计模式:Go常用设计模式概述

设计模式是啥呢&#xff1f;简单来说&#xff0c;就是将软件开发中需要重复性解决的编码场景&#xff0c;按最佳实践的方式抽象成一个模型&#xff0c;模型描述的解决方法就是设计模式。使用设计模式&#xff0c;可以使代码更易于理解&#xff0c;保证代码的重用性和可靠性。 …

P8681 [蓝桥杯 2019 省 AB] 完全二叉树的权值

题目描述 给定一棵包含 &#xfffd;N 个节点的完全二叉树&#xff0c;树上每个节点都有一个权值&#xff0c;按从上到下、从左到右的顺序依次是 &#xfffd;1,&#xfffd;2,⋯&#xfffd;&#xfffd;A1​,A2​,⋯AN​&#xff0c;如下图所示&#xff1a; 现在小明要把相同…

图论基础(python蓝桥杯)

图的基本概念 图的种类 怎么存放图呢&#xff1f; 优化 DFS 不是最快/最好的路&#xff0c;但是能找到一条连通的道路。&#xff08;判断两点之间是不是连通的&#xff09; 蓝桥3891 import os import sys sys.setrecursionlimit(100000) # 请在此输入您的代码 n, m map(int,…

C语言程序编译和链接

在ANSI C的任何⼀种实现中&#xff0c;存在两个不同的环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执⾏的机器指令&#xff08;⼆进制指令&#xff09;。 第2种是执⾏环境&#xff0c;它⽤于实际执⾏代码。 如果再把编译器展开成3个过程&#xff0c;那就变…

基于SpringBoot + Vue实现的中国陕西民俗网设计与实现+毕业论文

介绍 本系统包含管理员、用户两个角色。 管理员角色&#xff1a;登录、用户管理功能、民俗介绍管理功能(发布和管理民俗文化的介绍文章)、公告信息管理功能(发布网站的重要通知和活动信息)、商品管理功能(对商家发布的商品进行监管)、商品评价管理功能(监管商品评价内容&#…

ES6 学习(二)-- 字符串/数组/对象/函数扩展

文章目录 1. 模板字符串1.1 ${} 使用1.2 字符串扩展(1) ! includes() / startsWith() / endsWith()(2) repeat() 2. 数值扩展2.1 二进制 八进制写法2.2 ! Number.isFinite() / Number.isNaN()2.3 inInteger()2.4 ! 极小常量值Number.EPSILON2.5 Math.trunc()2.6 Math.sign() 3.…

C++11 shared_from_this学习

最近学习网络变成发现一些C源码库中封装对象时会公有继承enable_shared_from_this&#xff1b; 用一个案例进行说明&#xff0c;案例代码如下&#xff1a; #include <iostream> #include <memory> #include <stdio.h>using namespace std;class C : public…

【NFS】NFS使用汇总

1. NFS介绍 NFS(Network File System)&#xff0c;网络文件系统&#xff0c;它可以让不同主机能够通过 TCP/IP 网络共享资源。它从宏观主体上简化来看&#xff0c;就是两部分&#xff1a;服务端和客户端。 服务端&#xff0c;可以认为它就是来存东西的&#xff0c;这个东西对…

jupyter 设置工作目录

本博客主要介绍&#xff1a; 如何为jupyter设置工作目录 1.打开 anaconda prompt , 执行 jupyter notebook --generate-config 执行这个命令后会生成一个配置文件 2. 打开jupyter_notebook_config.py文件编辑 搜索notebook_dir&#xff0c;把这行代码的注释取消&#xff0c;…

Pillow教程03:图像处理的基本步骤+分离split+合并merge+混合blend+composite遮罩

--------------Pillow教程集合--------------- Python项目18&#xff1a;使用Pillow模块&#xff0c;随机生成4位数的图片验证码 Python教程93&#xff1a;初识Pillow模块&#xff08;创建Image对象查看属性图片的保存与缩放&#xff09; Pillow教程02&#xff1a;图片的裁剪…

vue3使用富文本编辑器 Editor.js

一、安装 Editor.js npm i editorjs/editorjs --save 二、在页面中引入并使用 样式就不发了&#xff0c;自己按自己的来 三、转换语言&#xff0c;默认是英文 editor new EditorJS({holder: this.$refs.editor,// 自动聚焦autofocus: true,// 其他配置... tools: {},i18…

第十四届蓝桥杯第十题:蜗牛分享

问题描述 输入格式 输出格式 输出共一行&#xff0c;一个浮点数表示答案&#xff08;四舍五入保留两位小数&#xff09;。 样例输入 3 1 10 11 1 1 2 1样例输出 4.20样例说明 蜗牛路线&#xff1a;(0,0)→(1,0)→(1,1)→(10,1)→(10,0)→(11,0)(0,0)→(1,0)→(1,1)→(10,1…

浏览器工作原理与实践--栈空间和堆空间:数据是如何存储的

对于前端开发者来说&#xff0c;JavaScript的内存机制是一个不被经常提及的概念 &#xff0c;因此很容易被忽视。特别是一些非计算机专业的同学&#xff0c;对内存机制可能没有非常清晰的认识&#xff0c;甚至有些同学根本就不知道JavaScript的内存机制是什么。 但是如果你想成…

【aws】架构图工具推荐

碎碎念 以前以为日本冰箱论是个梗&#xff0c;结果居然是真的。用光盘传真其实还能理解&#xff08;毕竟我也喜欢电子古董2333&#xff09;&#xff0c;但是画架构图居然用的是excel&#xff0b;截图&#xff01;啊苍天呐&#xff0c;然后看到隔壁工位用excel画web原型又感觉释…

【力扣】300. 最长递增子序列(DFS+DP两种方法实现)

目录 题目传送最长递增子序列[DFS 方法]DFS方法思路图思路简述代码大家可以自行考虑有没有优化的方法 最长递增子序列[DP]方法DP方法思路图思路简述代码方案 题目传送 原题目链接 最长递增子序列[DFS 方法] DFS方法思路图 思路简述 对于序列中的每一个数字只有选择和不选择两…

Echarts地图之——如何给地图添加外边框轮廓

有时候我们希望给地图外围加一圈边框来增加美感 但实际情况中&#xff0c;我们需要把国界的边框和各个省份属于国界的边框相吻合&#xff0c;否则就会造成两者看起来是错位的感觉 这就需要我们把echarts registerMap的全国省份json和国界边框json的坐标相一致。 这个json我们可…

Java项目实战笔记--基于SpringBoot3.0开发仿12306高并发售票系统--(二)项目实现-第五篇-核心功能车票预定开发及nacos集成

本文参考自 Springboot3微服务实战12306高性能售票系统 - 慕课网 (imooc.com) 本文是仿12306项目实战第&#xff08;二&#xff09;章——项目实现 的第五篇&#xff0c;本篇讲解该项目的核心功能——余票查询、车票预定功能的基础版开发&#xff0c;以及讲解项目与Nacos的集成…