缓存和数据库一致性问题分析
目录
1、数据不一致的原因
1.1 并发操作
1.2 非原子操作
1.3 数据库主从同步延迟
2、数据不一致的解决方案
2.1 并发操作
2.2 非原子操作
2.3 主从同步延迟
2.4 最终方案
3、不同场景下的特殊考虑
3.1 读多写少的场景
3.2 读少写多的场景
1、数据不一致的原因
导致缓存和数据库数据不一致的原因有三个
- 并发操作
- 非原子操作
- 数据库主从同步延迟
1.1 并发操作
假设数据库的原数据为x=0,考虑两种并发情况
- 两个线程同时写入
- 一个线程读,一个线程写
有以下4种方案
- 先更新缓存,后更新数据库
- 先更新数据库,后更新缓存
- 先删除缓存,再更新数据库
- 先更新数据库,再删除缓存
(1)先更新缓存,后更新数据库
两个线程同时写入
- A更新缓存,x=1
- B更新缓存,x=2
- B更新数据库,x=2
- A更新数据库,x=1
最终缓存为2,数据库为1
一个线程读,一个线程写
- A读取缓存发现没有命中,于是读取数据库,得到x=0
- B更新缓存,x=1
- B更新数据库,x=1
- A更新缓存,x=0
最终缓存为0,数据库为1
这种情况发生的概率极小,需要同时满足几个条件
- 第一,缓存不存在
- 第二,A的更新缓存命令 后于 B的更新缓存命令(基本不可能发生)
- 第三,A读取数据库+更新缓存的时间 > B更新缓存+B更新数据库的时间(基本不可能发生,因为写数据库的耗时大概率是比读数据库慢)
(2)先更新数据库,后更新缓存
两个线程同时写入
- A更新数据库,x=2
- B更新数据库,x=1
- B更新缓存,x=1
- A更新缓存,x=2
最终缓存为2,数据库为1
一个线程读,一个线程写
- A读取缓存发现没有命中,于是读取数据库,得到x=0
- B更新数据库,x=1
- B更新缓存,x=1
- A更新缓存,x=0
最终缓存为0,数据库为1
这种情况发生的概率也是极小,跟方案2的发生条件一样。
(3)先删除缓存,再更新数据库
两个线程同时写入
由于是删除缓存,多线程同时更新的话,缓存都是会被删除,没有讨论意义
一个线程读,一个线程写
- A读取缓存发现没有命中,于是读取数据库,得到x=0
- B删除缓存
- A更新缓存,x=0
- B更新数据库,x=1
最终,缓存是0,数据库是1
(4)先更新数据库,再删除缓存
两个线程同时写入
由于是删除缓存,多线程同时更新的话,缓存都是会被删除,没有讨论意义
一个线程读,一个线程写
- A读取缓存发现没有命中,于是读取数据库,得到x=0
- B更新数据库,x=1
- B删除缓存
- A更新缓存,x=0
最终,缓存是0,数据库是1
这种情况发生的概率也是极小,需要同时满足几个条件
- 第一,缓存不存在
- 第二,B更新数据库+删除缓存的时间 < A读取数据库+更新缓存的时间 (基本不可能发生,因为写数据库的耗时大概率是比读数据库慢)
1.2 非原子操作
非原子操作很好理解,就是因为操作缓存和操作数据库是两步操作,所以当第二步操作失败时,就会导致数据不一致问题。
1.3 数据库主从同步延迟
以上都只考虑了单机数据库的情况,对于主从数据库还有另一个问题,就是主从同步延迟
考虑以下情况
一个往主库写入,一个从从库读取
- A更新主库,x=1
- A删除缓存
- B查询缓存没有命中,查询从库,得到x=0
- 从库同步主库,更新为x=1
- B更新缓存,x=0
最终,缓存是0,数据库是1
2、数据不一致的解决方案
2.1 并发操作
根据1.1的几种方案,『先更新数据库,再删除缓存』是最好的。
2.2 非原子操作
最简单的解决办法就是重试,但是重试也要考虑一些问题:
- 立即重试的话大概率会失败;
- 重试次数设置多少比较合适;
- 同步重试会一直占用资源;
- 重试的过程中服务重启,会导致重试的操作消失,数据会一直不一致
所以就能想到异步重试方法,也就是把重试的这个操作写入到消息队列里,由另一个线程专门来处理重试的操作,而且消息队列本身可以保证消息不丢失(不丢失有两个方面,一是消息持久化,二是只有正确被消费掉了才会删除)
除了消息队列这中异步重试方案外,业界还有一种监听数据库bin log的方式,监听到变化后再去操作缓存,但是这种会额外引入其他的中间件而且实现复杂,综合而言没有消息队列的方案好用。
2.3 主从同步延迟
主从同步延迟的解决方案也很明显,就是延迟删除缓存,但是延迟多久再执行删除呢?这个就要靠经验了,一般来说1~5秒不等,看具体业务
所以在之前方案的基础上,引入延迟删除可以解决主从同步延迟的问题。
2.4 最终方案
1)更新数据库
2)删除缓存
3)如果删除失败则额外写入一条重试删除命令到消息队列
4)最后写入一个延迟删除命令到消息队列
3、不同场景下的特殊考虑
3.1 读多写少的场景
这种场景下,redis的作用是为了减轻数据库读取压力、加速读取,往往能接受一定的数据延迟,即保证最终一致性即可。
- 读多,所以删除缓存操作会导致缓存穿透问题(key不存在,大量请求命中数据库)
- 写少,所以基本不存在并发写入的问题,但是会存在并发读取和写入的问题
所以,读多写少的场景下,方案3和4是容易出现大问题的。
方案1和方案2是相对能接受的,但是也会有一定概率存在并发写入导致数据不一致的问题。
此时我们可以通过给缓存设置过期时间,使得数据保证最终一致性。
3.2 读少写多的场景
这种场景下,redis的作用是为了减轻数据库写入压力,对数据的一致性要求较高。
- 读少,所以并发读取和写入的情况比较少
- 写多,所以并发写入的情况比较多
由于并发写入情况比较多,此时方案3和4比较好,根据上文的分析,方案4比方案3更好。
相关文章:
缓存和数据库一致性问题分析
目录 1、数据不一致的原因 1.1 并发操作 1.2 非原子操作 1.3 数据库主从同步延迟 2、数据不一致的解决方案 2.1 并发操作 2.2 非原子操作 2.3 主从同步延迟 2.4 最终方案 3、不同场景下的特殊考虑 3.1 读多写少的场景 3.2 读少写多的场景 1、数据不一致的原因 导致…...
用Rust生成Ant-Design Table Columns | 京东云技术团队
经常开发表格,是不是已经被手写Ant-Design Table的Columns整烦了? 尤其是ToB项目,表格经常动不动就几十列。每次照着后端给的接口文档一个个配置,太头疼了,主要是有时还会粘错就尴尬了。 那有没有办法能自动生成colu…...
java.lang.ClassNotFoundException: sun.misc.BASE64Decoder
有一个新的应用服务,idea启动应用应用服务时,突然报错java.lang.ClassNotFoundException: sun.misc.BASE64Decoder ,然后在网上搜索,说是建议使用apache包,该类新的JRE已经废弃,并从rt.jar包中移除。但是该…...
Unity进阶--对象池数据场景管理器笔记
文章目录 泛型单例类泛型单例类(不带组件版)对象池管理器数据管理器场景管理器 泛型单例类 using System.Collections; using System.Collections.Generic;public abstract class ManagersSingle<T> where T : new() {private static T instance;…...
【Seata】微服务集成seata
文章目录 1、Seata介绍2、Seata架构3、部署TC服务4、微服务集成seata 1、Seata介绍 Seata是 2019 年 1 月份蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案。 官网http://seata.io/ 2、Seata架构 Seata事务管理有三个角色: TC (Transaction Coordinator) - 事务…...
解决react,<img>src使用require方法引入图片不显示问题
{settingList.map(i > (<img src{require(./images/${i.deviceTypeName}.png).default} />))} 解决方法: 再导入的图片后加.default即可 <img src{require(../../images/bg.png).default} alt"" /> 推荐阅读:https://www.cnb…...
从小白到大神之路之学习运维第67天-------Tomcat应用服务 WEB服务
第三阶段基础 时 间:2023年7月25日 参加人:全班人员 内 容: Tomcat应用服务 WEB服务 目录 一、中间件产品介绍 二、Tomcat软件简介 三、Tomcat应用场景 四、安装配置Tomcat 五、配置目录及文件说明 (一)to…...
图解SQL基础知识,小白也能看懂的SQL文章
本文介绍关系数据库的设计思想: 在 SQL 中,一切皆关系。 在计算机龄域有许多伟大的设计理念和思想,例如: 在 Unix 中,一切皆文件。 在面向对象的编程语言中,一切皆对象。 关系数据库同样也有自己的设计…...
自动驾驶感知系统-毫米波雷达
毫米波雷达就是电磁波,雷达通过发射无线电信号并接收反射信号来测定车辆与物体间的距离,其频率通常介于10~300GHz之间。与厘米波导引头相比,毫米波导引头体积小,质量轻,空间分辨率高;与红外、激光、电视等光…...
Esp32_Arduino接入腾讯云笔记
ESP32是一款由乐鑫科技(Espressif Systems)推出的双核、低功耗、集成Wi-Fi和蓝牙的单芯片微控制器。它采用了Tensilica Xtensa LX6高性能处理器,具有大量的GPIO引脚、模数转换器、SPI、I2S、UART、PWM、I2C和SD卡接口等功能,可以满…...
python简单入门
python简单入门 文章目录 python简单入门0. 地址链接1. 官网2.2. 下载地址3. 官方文档 1. 第一章1.1 python解释器1.2 基础语法1.2.1 常见数据类型1.2.2 强制类型转换1.2.3 注释1.2.4 运算符1.2.5 字符串1.2.5.1 字符串的定义1.2.5.2 字符串拼接1.2.5.3 格式化字符串1.2.5.3 精…...
如何快速从csv文件搭建一个简单的神经网络模型(回归)
快速搭建一个简单的神经网络预测模型 采用的数据是kaggle的房价预测数据 涉及的数据文件,提取码为:zxcv #导入相关包 import pandas as pd import numpy as np import torch import torch.nn as nn首先读取数据 trainpd.read_csv("path",enc…...
Pytorch深度学习-----DataLoader的用法
系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用(ToTensor,Normalize,Resize ,Co…...
macOS Ventura 13.5 (22G74) Boot ISO 原版可引导镜像下载
macOS Ventura 13.5 (22G74) Boot ISO 原版可引导镜像下载 本站下载的 macOS 软件包,既可以拖拽到 Applications(应用程序)下直接安装,也可以制作启动 U 盘安装,或者在虚拟机中启动安装。另外也支持在 Windows 和 Lin…...
【机器学习】 奇异值分解 (SVD) 和主成分分析 (PCA)
一、说明 在机器学习 (ML) 中,一些最重要的线性代数概念是奇异值分解 (SVD) 和主成分分析 (PCA)。收集到所有原始数据后,我们如何发现结构?例如,通过过去 6 天…...
如何用logging记录python实验结果?
做python实验有时候需要打印很多信息在控制台(console),但是控制台的信息不方便回顾和保存,故而可以采用logging将信息存储起来。 先新建一个文件message.log代码如下: import logging logging.basicConfig(filename"messa…...
C语言假期作业 DAY 03
目录 题目 一、选择题 1、已知函数的原型是: int fun(char b[10], int *a); ,设定义: char c[10];int d; ,正确的调用语句是( ) 2、请问下列表达式哪些会被编译器禁止【多选】( ) 3、…...
使用serverless实现从oss下载文件并压缩
公司之前开发一个网盘系统, 可以上传文件, 打包压缩下载文件, 但是在处理大文件的时候, 服务器遇到了性能问题, 主要是这个项目是单机部署.......(离谱), 然后带宽只有100M, 现在用户比之前多很多, 然后所有人的压缩下载请求都给到这一台服务器了, 比如多个人下载的时候带宽问…...
从上到下打印二叉树
题目描述 从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。 例如: 给定二叉树: [3,9,20,null,null,15,7], 返回: [3,9,20,15,7] 算法思想 建立一个vector数组ret用来当做返回的结果数组,建立一个队列用来接收二叉树…...
【推荐】排序模型的调优
【推荐】排序模型的调优 排序模型的选择 排序模型常见的训练方式 样本类别不均衡处理尝试 欠拟合 过拟合 其他问题 排序模型的选择 LR,GBDT,LRGBDT,FM/FFM, 深度模型(wide & deep,DeepFM&#x…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
