如何保证Redis和数据库数据一致性
缓存可以提升性能,减轻数据库压力,在获取这部分好处的同时,它却带来了一些新的问题,缓存和数据库之间的数据一致性问题。
想必大家在工作中只要用了咱们缓存势必就会遇到过此类问题
首先我们来看看一致性:
- 强一致性:任何一次读都能读到某个数据的最近一次写的数据。
- 弱一致性:数据更新后,如果能容忍后续的访问只能访问到部分或者全部访问不到,则是弱一致性。
1.读取数据

- 当应用程序需要从数据库读取数据时,先检查缓存数据是否命中。
- 如果缓存未命中,则查询数据库获取数据,同时将数据写到缓存中,以便后续读取相同数据会命中缓存,最后再把数据返回给调用者。
- 如果缓存命中,直接返回。
单独的只读取数据场景是不会出现不一致。 只有读和写一起才会出现 , 那我们再来说下写数据的场景
问题:如果数据库中的某条数据放入缓存后,又马上被更新了,那我们应该如何更新缓存
2.写数据
当我们对数据进行修改的时候,到底是先删缓存,还是先写数据库?
- 先更新缓存再更新数据库
- 先删除缓存再更新数据库
- 先更新数据库再更新缓存
- 先更新数据库再删除缓存
无非就是缓存用更新或用删除?推荐直接删除
为什么不更新?而直接删, 因为缓存的更新成本更高(因为你写入数据库的值,很多情况并不是直接写入缓存的,而是要经过一系列复杂的计算再写入缓存。那么,每次写入数据库后,都再次计算写入缓存的值,无疑是浪费性能的。显然,删除缓存更为适合。)删除缓存操作简单,副作用只是增加了一次 chache miss,建议大家使用该策略。
先操作数据库还是先操作缓存?
2.先操作缓存
2.1先更新缓存,再更新数据库

缺点:如果先更新缓存成功,在更新数据库的时候失败,这时候会导致数据不一致;缓存的作用是不是临时将我们数据保存在内存,便于提高查询速度;但是如果某条数据在数据库中都不存在,缓存这种数据没有一点意义
2.2.先删除缓存,再更新数据库

缺点:高并发场景下,如果多个线程同时执行更新数据库再写缓存操作可能会出现数据库是新值,而缓存中是旧值

2.3.先删缓存再删数据库

先删缓存再删数据库:在多线程环境下,当一个线程把缓存删掉之后,另一个线程读缓存,读不到缓存就会直接读库,读到数据后就会更新缓存,先前的线程呢,才更新数据库,会造成缓存脏读的情况,很容易产生缓存脏读。
而且,如果不采用给缓存设置过期时间策略,该数据永远都是脏数据。
3.先操作数据库
3.1.先更新数据库,再更新缓存

优点:可以解决先更新缓存,再更新数据库带来的假数据问题
缺点:高并发场景下,如果多个线程同时执行更新数据库再写缓存操作可能会出现数据库是新值,而缓存中是旧值

3.2.先更新数据库,再删除缓存
在高可用的系统系统里面,我们追求数据最终一致性的话,我们可以考虑先更新数据库,再去删除缓存
也算是常用的方案,这里介绍一下,这个叫 Cache Aside Pattern。如果先更新数据库,再删除缓存,那么就会出现更新数据库之前有瞬间数据不是很及时。
同时,如果在更新之前,缓存刚好失效了,读客户端有可能读到旧值,然后在写客户端删除结束后再次设置了旧值,非常巧合的情况。
有 2 个前提条件:缓存在写之前的时候失效,同时,在写客户度删除操作结束后,放置旧数据 — 也就是读比写慢。设置有的写操作还会锁表。
这个很难出现,但是如果出现了怎么办?使用双删!!!



3.3先删数据库再删缓存

先删数据库再删缓存,在多线程情况下,当一个线程删除数据库,另一个线程读取缓存数据,读到的是缓存的数据,当先前一个线程删完数据库后就会更新缓存,这是缓存就正常了,产生了一次脏读。
5.解决
5.1.强一致性?
在强一致性系统中,通过2PC、Paxos或分布式锁保持一致性可能会成为影响系统吞吐量、响应时间和可伸缩性的昂贵开销, 因此通常采用一种相当宽松的一致性方法,称为最终一致性。
5.2.最终一致性:延时双删

关键:间隔一段时间再删除是为了保证并发读请求写入的旧值最终能够被第二次删除删除掉
缺点:延时双删可能对我们性能要求方面不能有太高的要求
注意:我们需要自行评估项目的读数据业务逻辑的耗时(即线程二从数据库读取数据 写入缓存完成), 防止线程二覆盖掉新数据
如果第二次删除缓存失败怎么办?
4.为了防止删除缓存失败,可以进行重试机制
- 同步重试,如果并发量高的时候可能会影响接口性能
- 异步重试:
- 创建单独的一个线程,进行重试;但是在高并发的场景下,可能会因为创建线程太多,导致OOM
- 交给线程池处理;但是如果服务重启,会导致数据丢失
- 重试数据写入表,通过定时任务重试(可以保证数据不丢失,但是对于实时性要求较高的该场景不太适用)
- 利用MQ消息中间件进行重试,在消费者中处理

- 订阅mysql的binlong,在订阅者中,如果发现更新数据请求,则删除响应的缓存,比如使用canal中间件;为了保证删除缓存成功,可以增加MQ

6.总结
缓存策略的最佳实践是 **Cache Aside Pattern。**分别分为读缓存最佳实践和写缓存最佳实践。
读缓存最佳实践:先读缓存,命中则返回;未命中则查询数据库,再写到数据库。
写缓存最佳实践:
- 先写数据库,再操作缓存;
- 直接删除缓存,而不是修改,因为缓存的更新成本很高,删除缓存操作简单,副作用只是增加了一次 chache miss,建议大家使用该策略。
在以上最佳实践下,为了尽可能保证缓存与数据库的一致性,我们可以采用延迟双删。
防止删除失败,我们采用异步重试机制保证能正确删除,异步机制我们可以发送删除消息到 mq 消息中间件,或者利用 canal 订阅 MySQL binlog 日志监听写请求删除对应缓存。
那么,如果我非要保证绝对一致性怎么办,先给出结论:
没有办法做到绝对的一致性,这是由 CAP 理论决定的,缓存系统适用的场景就是非强一致性的场景,所以它属于 CAP 中的 AP。
所以,我们得委曲求全,可以去做到 BASE 理论中说的最终一致性。
其实一旦在方案中使用了缓存,那往往也就意味着我们放弃了数据的强一致性,但这也意味着我们的系统在性能上能够得到一些提升。
相关文章:
如何保证Redis和数据库数据一致性
缓存可以提升性能,减轻数据库压力,在获取这部分好处的同时,它却带来了一些新的问题,缓存和数据库之间的数据一致性问题。 想必大家在工作中只要用了咱们缓存势必就会遇到过此类问题 首先我们来看看一致性: 强一致性…...
css3常见选择器
使用工具 Visual Studio Code 1.CSS3基础选择器 1.1 标签选择器 1.2.1 标签选择器的语法 一个完整的HTML5页面是由很多不同的标签组成的,而标签选择器则决定标签应采用的CSS样式,语法如下:标签名{ 属性1:属性值1; 属性2&…...
List(CS61B学习记录)
问题引入 上图中,赋给b海象的weight会改变a海象的weight,但x的赋值又不会改变y的赋值 Bits 要解释上图的问题,我们应该从Java的底层入手 相同的二进制编码,却因为数据类型不同,输出不同的值 变量的声明 基本类型…...
Python 导入Excel三维坐标数据 生成三维曲面地形图(面) 1、线条折线曲面
环境和包: 环境 python:python-3.12.0-amd64包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 代码: import pandas as pd import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D from matplotlib.colors import ListedColor…...
2024年华为HCIA-DATACOM新增题库(H12-811)
801、[单选题]178/832、在系统视图下键入什么命令可以切换到用户视图? A quit B souter C system-view D user-view 试题答案:A 试题解析:在系统视图下键入quit命令退出到用户视图。因此答案选A。 802、[单选题]“网络管理员在三层交换机上创建了V…...
离线安装数据库 mysql 5.7 linux
离线安装数据库 mysql 5.7 linux 方法一 参考链接Linux(Debian10.2)安装MySQL5.7.24环境 赋予文件执行权限chmod x 文件名 使用root用户sudo su解压文件tar xvf mysql-5.7.42-linux-glibc2.12-x86_64.tar.gz重命名mv mysql-5.7.42-linux-glibc2.12-x86_64 mysql将桌面的mys…...
2024-03-14学习笔记(YoloV9)
1.认知越高的人,越敬畏因果 摘要:本文讲述了认知越高的人越敬畏因果的道理。通过故事和名人案例,阐述了敬畏因果对于个人成长和成功的重要性。文章强调了遵循规律、不走捷径、正向思维的重要性,以及思维、行动、习惯、性格和命运…...
Cookie和Session介绍
1、Cookie的一些重要结论(令牌,类似就诊卡记住我们的信息): (1)Cookie从哪里来:服务器返回给浏览器的,通常是首次访问/登录成功之后(cookie是在header中传输)…...
OpenCV 将rgb图像转化成字符图像
将RGB图像转换成字符图像(ASCII art)通常涉及到灰度化、降采样、映射字符等一系列步骤。以下是一个简化的OpenCVC实现示例: #include <opencv2/opencv.hpp> #include <iostream> #include <string>// 字符映射表ÿ…...
ios开发错误积累
1.xcode 下载模拟器报错 Could not download iOS 报错: 解决: 1、去官网下载自己需要 地址(https://developer.apple.com/download/all) 2、下载完成后,执行以下命令添加:xcrun simctl runtime add /路径…...
软件实际应用实例,物流打印用什么软件,佳易王物流货运快运单打印查询管理系统软件,可以在已经印刷好的单子上打印,也可直接打印
软件实际应用实例,物流打印用什么软件,佳易王物流货运快运单打印查询管理系统软件,可以在已经印刷好的单子上打印,也可直接打印 一、前言 以下软件教程以 佳易王物流单打印查询管理系统软件V17.0为例说明 软件文件下载可以点击…...
第六届上海国际垃圾焚烧发电展将于12月11-13日上海举办
第六届上海国际垃圾焚烧发电暨固废处理技术展览会 2024年12月11-13日 上海新国际博览中心 主办单位:中华环保联合会 废弃物发电专委会 支持单位:垃圾焚烧技术与装备国家工程实验室 承办单位:上海怡涵展览服务有限公司 展会介绍:…...
pytorch(十)循环神经网络
文章目录 卷积神经网络与循环神经网络的区别RNN cell结构构造RNN例子 seq2seq 卷积神经网络与循环神经网络的区别 卷积神经网络:在卷积神经网络中,全连接层的参数占比是最多的。 卷积神经网络主要用语处理图像、语音等空间数据,它的特点是局部…...
【黑马程序员】Python文件、异常、模块、包
文章目录 文件操作文件编码什么是编码为什么要使用编码 文件的读取openmodel常用的三种基础访问模式读操作相关方法 文件的写入注意代码示例 异常定义异常捕获捕获指定异常捕获多个异常捕获所有异常异常else异常finally 异常的传递 python 模块定义模块的导入import模块名from …...
导入fetch_california_housing 加州房价数据集报错解决(HTTPError: HTTP Error 403: Forbidden)
报错 HTTPError Traceback (most recent call last) Cell In[3], line 52 from sklearn.datasets import fetch_california_housing3 from sklearn.model_selection import train_test_split ----> 5 X, Y fetch_california_housing(retu…...
后勤管理系统|基于SSM 框架+vue+ Mysql+Java+B/S架构技术的后勤管理系统设计与实现(可运行源码+数据库+设计文档+部署说明+视频演示)
目录 文末获取源码 前台首页功能 员工注册、员工登录 个人中心 公寓信息 员工功能模块 员工积分管理 管理员登录 编辑管理员功能模块 个人信息 编辑员工管理 公寓户型管理 编辑公寓信息管理 系统结构设计 数据库设计 luwen参考 概述 源码获取 文末获取源…...
【办公类-40-01】20240311 用Python将MP4转MP3提取音频 (家长会系列一)
作品展示: 背景需求: 马上就要家长会,我负责做会议前的照片滚动PPT,除了大量照片视频,还需要一个时间很长的背景音乐MP3 一、下载“歌曲串烧” 装一个IDM 下载三个“串烧音乐MP4”。 代码展示 家长会背景音乐: 歌曲串…...
人类的谋算与量子计算
量子计算并不等价于并行计算。量子计算和并行计算是两种不同的计算模型。 在经典计算中,通过增加计算机的处理器核心和内存等资源,可以实现并行计算,即多个任务同时进行。并行计算可以显著提高计算速度,尤其是对于可以被细分为多个…...
【数据结构和算法初阶(C语言)】栈的概念和实现(后进先出---后来者居上的神奇线性结构带来的惊喜体验)
目录 1.栈 1.1栈的概念及结构 2.栈的实现 3.栈结构对数据的处理方式 3.1对栈进行初始化 3.2 从栈顶添加元素 3.3 打印栈元素 3.4移除栈顶元素 3.5获取栈顶元素 3.6获取栈中的有效个数 3.7 判断链表是否为空 3.9 销毁栈空间 4.结语及整个源码 1.栈 1.1栈的概念及结构 栈&am…...
搭建mysql主从复制(主主复制)
1:设主库允许远程连接(注意:设置账号密码必须使用的插件是mysql_native_password,其他的会连接失败) #切换到mysql这个数据库,修改user表中的host,使其可以实现远程连接 mysql>use mysql; mysql>update user se…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
