当前位置: 首页 > news >正文

解决MySQL与Redis缓存一致性的问题

背景

考试系统中,教师会在后台发布一场考试,考试会存储在MySQL和Redis里面,考试有时候是会出错的,我们需要后台修改,如果多个教师在后台并发修改(概率不大),可能会出现数据库缓存不一致的问题,我们需要解决一下,刚好联系一下这一块的知识

基础知识理论

四种解决办法:

  1. 先更新数据库,再更新缓存
  2. 先更新缓存,后更新数据库
  3. 先删除缓存,后更新数据库
  4. 先更新数据库,后删除缓存

这四种情况,都会出现缓存不一致的问题,但是第四种出现缓存不一致的情况概率上比较低,因为缓存的写入回远远快于数据库的写入,我们可以使用【先更新数据库+再更新缓存】的方式来解决数据库不一致的问题,为了确保万无一失,我们还可以加上一个过期时间。

但是有两个问题

  1. 我们需要保证先更新数据库+再更新缓存是一个原子操作,不然如果更新缓存失败了,导致缓存中的数据还是旧值
  2. 「先更新数据库,再删除缓存」的方案虽然保证了数据库与缓存的数据一致性,但是每次更新数据的时候,缓存的数据都会被删除,这样会对缓存的命中率带来影响。

对于第一个问题,解决办法是消息队列重试机制、订阅MySQL binlog,再操作缓存

对于第二个问题是,我们使用「更新数据库 + 更新缓存」的方式来实现,但是这个方案本身固有一些问题,解决办法是,分布式锁和过期时间

另外先删除缓存,再更新数据库的解决方案是延迟双删

实战-先更新数据库,后删除缓存

此种方案存在问题是两个操作不是原子性的,如何保证两个操作都能成功呢?

方案一:gin框架+消息队列

我们实现一个中间件

func Canal() gin.HandlerFunc {//封装成一个中间件,当我们更新考试的时候,会自动监测到return func(c *gin.Context) {c.Next()redisDB := global.GVA_REDISget, exists := c.Get("DeleteRedisKey")DeleteKey := get.(string)if exists {err := redisDB.Del(context.Background(), DeleteKey).Err()if err == redis.Nil {//无需删除c.Next()} else if err != nil {//删除失败,加入到redis异步队列中,再次删除addToDelayedQueue(context.Background(), redisDB, DeleteKey, time.Now().Add(10*time.Second))}else {global.GVA_LOG.Info("更新数据成功")}} else {zap.L().Info("redis中不存在该键,无需删除")}}
}

我们在继承这个中间件的接口中的使用c.Set方法传递要删除的redisKey,然后我们在上述中间件中使用c.Get方法来接收要删除的redisKey,然后加入到异步队列中删除

现在来模拟一下是否能够成功,项目启动之后,把redis停机,然后删除redis的key就会失败,然后该key就会加入延时队列

方案一:消息队列订阅binlog

里面有两个难点,一个是订阅binlog服务,一个是消息队列

 如何订阅binlog服务,我们使用阿里巴巴的canal ,支持Go语言,具体参考Golang通过alibabaCanal订阅MySQLbinlog_大杯无糖的博客-CSDN博客

接下来是用redis的zset实现一个异步消息队列

相关文章:

解决MySQL与Redis缓存一致性的问题

背景 考试系统中,教师会在后台发布一场考试,考试会存储在MySQL和Redis里面,考试有时候是会出错的,我们需要后台修改,如果多个教师在后台并发修改(概率不大),可能会出现数据库缓存不…...

王道机组难题分析

第四章 指令系统 大端方式:就是高地址存放高位, LSB的意思是:全称为Least Significant Bit,在二进制数中意为最低有效位 MSB的意思是:全称为Most Significant Bit,在二进制数中属于最高有效位 操作数可以理…...

数学建模(一)前继概念

课程推荐:数学建模老哥_哔哩哔哩_bilibili 目录 一、什么是数学建模? 二、数学建模的一般步骤 三、数学建模赛题类型 1.预测型 2. 评价类 3.机理分析类 4. 优化类 一、什么是数学建模? 数学建模是利用数学方法解决实际问题的一种实践。…...

C# 随机法求解线性规划问题 蒙特卡洛

线性规划问题: max3x12x2 x12x2<5 2x1x2<4 4x13x2<9 x1>0 x2>0 正确的结果:x11.5; x21, max z6.5 Random random1 new Random(DateTime.Now.Millisecond);Random random2 new Random(DateTime.Now.Millisecond*DateTime.Now.Millisecond);double max-9999,x1…...

nginx文档合集

1、nginx documentation 2、14个Nginx的核心功能点&#xff0c;建议收藏&#xff01; 3、Nginx之负载均衡模块 ngx_http_upstream_module_途径日暮不赏丶的博客-CSDN博客 4、tomcat redis session共享 https://github.com/redisson/redisson/tree/master/redisson-tomcat...

什么是BFC?它有什么作用?如何创建BFC?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是BFC⭐ BFC的作用⭐ 创建BFC的方法⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web…...

svn文章四:版本控制策略 - 穿越时光机:SVN版本控制进阶技巧

文章四&#xff1a;版本控制策略 - “穿越时光机&#xff1a;SVN版本控制进阶技巧” 概述&#xff1a;版本控制是SVN的核心功能。本文将深入研究SVN版本控制的进阶技巧&#xff0c;包括标签管理、历史查看、版本回退等&#xff0c;让您成为版本控制的高手。 1. 引言 版本控制…...

SpringBoot+Mybatis-Plus实现增删改查超详细步骤

目录 一、介绍 二、前期准备工作 &#xff08;一&#xff09; 创建springboot项目和创建数据库 三、项目配置 &#xff08;一&#xff09;pom.xl导入相关依赖 1.导入依赖 &#xff08;二&#xff09;yml文件中配置连接数据库 2.配置yml文件 四、代码的编写 数据库展…...

Qt应用开发(基础篇)——拆分器窗口 QSplitter QSplitterHandle

一、前言 QSplitter继承于QFrame&#xff0c;QFrame继承于QWidget&#xff0c;是Qt的一个部件容器工具类。 框架类QFrame介绍 QSplitter拆分器&#xff0c;用户通过拖动子部件之间的边界来控制子部件的大小&#xff0c;在应用开发中数据分模块展示、图片展示等场景下使用。 二、…...

屏幕尺寸单位 px、em、rem区别

1、px是屏幕设备物理上能显示出的最小的一个点&#xff0c;这个点不是固定宽度的&#xff0c;不同设备上点的长宽、比例有可能会不同。假设&#xff1a;1号显示器上1px宽1毫米&#xff0c;但2号显示器1px宽两毫米&#xff0c;那么定义一个div宽度为100px&#xff0c;1号显示器上…...

yo!这里是STL::list类简单模拟实现

目录 前言 重要接口实现 框架 默认成员函数 迭代器&#xff08;重点&#xff09; 1.引言 2.list迭代器类实现 3.list类中调用实现 增删查改 后记 前言 我们知道&#xff0c;stl中的vector对应数据结构中的顺序表&#xff0c;string类对应字符串&#xff0c;而今天要…...

小程序商城开发制作

当开发一个商城小程序时&#xff0c;费用是一个非常重要的考虑因素。然而&#xff0c;准确回答这个问题是有一定困难的&#xff0c;因为开发商城小程序的费用取决于多个因素。以下是一些可能影响价格的主要因素&#xff1a; 1. 功能需求&#xff1a;商城小程序的复杂程度和功能…...

并发编程面试题2

并发编程面试题2 一、AQS高频问题&#xff1a; 1.1 AQS是什么&#xff1f; AQS就是一个抽象队列同步器&#xff0c;abstract queued sychronizer&#xff0c;本质就是一个抽象类。 AQS中有一个核心属性state&#xff0c;其次还有一个双向链表以及一个单项链表。 首先state…...

关于eclipse导入部署具有增删改查的项目

目录 前言&#xff1a;当我们刚刚进入公司的第一步就是去部署当前公司的项目&#xff0c;本博客就是详细介绍怎么去部署当前公司的项目。 一&#xff0c;开发工具&#xff1a; 二&#xff0c;具体步骤&#xff1a; 2.1导入公司的项目 打开eclipse开发工具 2.2配置当前的环…...

c++日志工具之——log4cpp

1、log4cpp概述 Log4cpp是一个开源的C类库&#xff0c;它提供了C程序中使用日志和跟踪调试的功能&#xff0c;它的优点如下&#xff1a; 提供应用程序运行上下文&#xff0c;方便跟踪调试&#xff1b; 可扩展的、多种方式记录日志&#xff0c;包括命令行、文件、回卷文件、内…...

ES索引重建reindex详解

目录 一、使用场景 二、reindex介绍 三、使用手册 1、覆盖更新 2、创建丢失的文档并更新旧版本的文档 3、仅创建丢失的文档 4、冲突处理 5、source中添加查询条件 6、source中包含多个源索引 7、限制处理的记录数 8、从远程ES集群中重建索引 9、提取随机子集 10、…...

前沿分享-中距离射频取电

目前来看&#xff0c;微能源有四种技术路线&#xff0c;一是环境光采集、温差转换采集、无线射频采集和振动能量采集。 无线射频微能源是在通信设备通信过程中自然产生的&#xff0c;可以通过射频能量芯片实现无线射频取电&#xff0c;能瞬间大功率储电和安全驱动负载。 通过射…...

UnrealEngine - 网络同步之连接篇

1 连接过程 - 握手 传统的 C/S 架构下&#xff0c;Client 和 Server 通常会建立一条抽象的 Connection&#xff0c;用来进行两端的通信。 UE 的官方文档中提供了 Client 连接到 Server 的示例 &#xff0c;简单来说分为如下几步&#xff1a; 打包构建好 Client 和 Server 进程…...

【JDBC系列】- 扩展提升学习

扩展提升学习 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f3c6; 博客首页 怒放吧德德 To记录领地 &#x1f31d;分享学习心得&#xff0c;欢迎指正&#xff0…...

阻塞和非阻塞,同步和异步

文章目录 典型的一次IO的两个阶段IO多路复用是同步还是异步&#xff1f; 典型的一次IO的两个阶段 数据就绪和数据读写 同步&#xff1a;需要应用程序自己操作 IO多路复用是同步还是异步&#xff1f; epoll也是同步的 具体数据读取还是通过应用程序自己完成的 只有使用了特…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

土建施工员考试:建筑施工技术重点知识有哪些?

《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目&#xff0c;核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容&#xff0c;附学习方向和应试技巧&#xff1a; 一、施工组织与进度管理 核心目标&#xff1a; 规…...

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...

文件上传漏洞防御全攻略

要全面防范文件上传漏洞&#xff0c;需构建多层防御体系&#xff0c;结合技术验证、存储隔离与权限控制&#xff1a; &#x1f512; 一、基础防护层 前端校验&#xff08;仅辅助&#xff09; 通过JavaScript限制文件后缀名&#xff08;白名单&#xff09;和大小&#xff0c;提…...

Redis上篇--知识点总结

Redis上篇–解析 本文大部分知识整理自网上&#xff0c;在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库&#xff0c;Redis 的键值对中的 key 就是字符串对象&#xff0c;而 val…...

Axure Rp 11 安装、汉化、授权

Axure Rp 11 安装、汉化、授权 1、前言2、汉化2.1、汉化文件下载2.2、windows汉化流程2.3、 macOs汉化流程 3、授权 1、前言 Axure Rp 11官方下载链接&#xff1a;https://www.axure.com/downloadthanks 2、汉化 2.1、汉化文件下载 链接: https://pan.baidu.com/s/18Clf…...