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

news2025/1/2 3:21:13

背景

考试系统中,教师会在后台发布一场考试,考试会存储在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_REDIS
		get, 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实现一个异步消息队列

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

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

相关文章

【mysql】MySQL CUP过高如何排查?

文章目录 一. 问题锁定二. QPS激增会导致CPU飘高三. 慢SQL会导致CPU飘高四. 大量空闲连接会导致CPU飘高五. MySQL问题排查常用命令 一. 问题锁定 通过top命令查看服务器CPU资源使用情况,明确CPU占用率较高的是否是mysqld进程,如果是则可以明确CUP飘高的原…

Java类和对象(一文读懂)

文章目录 类、对象是什么?创建类构造器 创建对象 类、对象是什么? 类:类是一个模板,它描述一类对象的行为和状态。类可以看成是创建 Java 对象的模板。 对象:对象是类的一个实例(对象不是找个女朋友&#x…

自动驾驶——驶向未来的革命性技术

自动驾驶——驶向未来的革命性技术 自动驾驶的组件自动驾驶的优势自动驾驶的应用自动驾驶的未来中国的自动驾驶 自动驾驶是一种技术,它允许车辆在没有人类驾驶员的情况下自主地进行行驶。它利用各种传感器、计算机视觉、人工智能和机器学习算法来感知和理解周围环境…

大模型开源,创业者又站在了同一起跑线

先聊聊最近接触的几个创业者,AI 领域的。有两位做艺术二维码变现的,一个模式比较简单 PSSD,另一个有点技术含量,预训练好几张图,让用户上传自己的二维码,再生成新的二维码,形式上要比 PS 的自动…

【单片机毕业设计】【hj-001】温度控制 | 恒温箱 | 保温箱 | 恒温孵化器 | 环境检测 | 温度检测

一、基本介绍 项目名: 基于单片机的温度控制系统设计 基于单片机的恒温箱系统设计 基于单片机的保温箱系统设计 基于单片机的恒温孵化器系统设计 基于单片机的环境检测系统设计 基于单片机的温度检测系统设计 项目编号:mcuclub-hj-001 单片机类型&…

Apache Paimon 在同程旅行的实践进展

摘要:本文整理自同程旅行大数据计算组负责人吴祥平,在 Apache Paimon Meetup 的分享。本篇内容主要分为四个部分: 1. Apache Paimon 引入 2. Apache Paimon 应用建设 3. Apache Paimon 优化实践 4. 未来规划和期待 Tips:点击「阅读…

VR虚拟现实素材大全助力开发者实现更加丰富的交互效果

VR虚拟现实素材大全由广州华锐互动开发,在VR虚拟现实项目制作中发挥着至关重要的作用。这些素材库提供了各种类型的3D模型、纹理、材质、灯光和特效,涵盖食品、建筑、汽车、运动、人物、科技等各个领域,使得开发者可以更加方便地构建逼真的虚…

数据库锁表 Lock wait timeout exceeded; try restarting transaction

锁等待超时 Lock wait timeout exceeded; try restarting transaction,是当前事务在等待其它事务释放锁资源造成的 解决办法 1、数据库中执行如下sql,查看当前数据库的线程情况: show full PROCESSLIST2、再到 INNODB_TRX 事务表中查看&…

一文教你如何创建 Python 虚拟环境

目录 前言一、配置虚拟环境1.1 Windows1.2 Linux 二、常用管理命令三、FAQ 前言 其实这都是 Python 基础该掌握的,今天博客记录一下,方便自己或其他人阅读。虚拟环境的好处在于达到环境上的隔离,如:不同的项目有自己独特的环境&a…

Spring Boot 统一功能处理(拦截器实现用户登录权限的统一校验、统一异常返回、统一数据格式返回)

目录 1. 用户登录权限校验 1.1 最初用户登录权限效验 1.2 Spring AOP 用户统⼀登录验证 1.3 Spring 拦截器 (1)创建自定义拦截器 (2)将自定义拦截器添加到系统配置中,并设置拦截的规则 1.4 练习:登录…

app测试和web测试的区别是什么?【软件测试经典面试题】

单纯从功能测试的层面上来讲的话: APP 测试、web 测试 在流程和功能测试上是没有区别的。 1.系统架构方面: web项目,一般都是b/s架构,基于浏览器的 app项目,则是c/s的,必须要有客户端,用户需…

AI绘画(1)stable diffusion安装教程

1、引言 stable diffusion 是一款免费开源的AI绘画工具,它能够帮助任何人轻松地进行绘画创作。不论你是有绘画基础还是完全没有经验,stable diffusion 都能让你在数字画布上释放创造力。 stable diffusion 提供了丰富多样的绘画工具和选项,…

公会在tiktok发展,有哪些国家,怎么入驻呢?

在秀场直播领域,众多公会都将目光聚焦在TikTok上。TikTok已成为一个新的金矿,许多公会已在这个平台上赚得盆满钵满。 这些公会在TikTok上月流水达到数百万美元,甚至在一场PK中流水达到40万美元,分成比例高达80%。TikTok的秀场直播…

PostGIS 矢量瓦片

title: PostGIS 矢量瓦片 date: 2023-08-07 author: ac tags: vector tile categories:Database Martin - 基于PostGIS的矢量瓦片服务器 1. 简介 目前流行的矢量瓦片的切图方案: mapbox gl tippecanoe :v2收费,tippecanoe是mapbox官方推…

【C语言】结构体详解

现实生活中一个事物,会有许多属性连接起来。而C语言引入一种构造数据类型——结构体 将属于一个事物的多个数据组织起来以体现其内部联系。 一、结构体类型的定义 结构体类型 是一种 构造类型,它是由若干成员组成的,每个成员可以是一个基本…

python:使用geopandas和rasterio将矢量范围内的栅格值赋为0并重新输出

需求:有一个点shp文件和一个栅格,想要构建shp中每个点的缓冲区,并且缓冲区范围内的栅格值重新赋为0并输出新的tif文件 解决方法:使用python中的geopandas和rasterio中的掩膜操作实现 代码如下: import numpy as np …

数据结构(一):顺序表详解

在正式介绍顺序表之前,我们有必要先了解一个名词:线性表。 线性表: 线性表是,具有n个相同特性的数据元素的有限序列。常见的线性表:顺序表、链表、栈、队列、数组、字符串... 线性表在逻辑上是线性结构,但…

【验证码逆向专栏】最新某度旋转验证码 v2 逆向分析

声明 本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未…

使用requests如何实现自动登录

不知道大家有没有注意到,好多网站我们登录过后,在之后的某段时间内访问该网页时,不会给出请登录的提示,时间到期后就会提示请登录!这样在使用爬虫访问网页时还要登录,打乱我们的节奏,那么如何使…

ISC 2023 大会成功举办,向量数据库公司 Zilliz 成大模型论坛焦点

近日,第十一届互联网安全大会(ISC 2023)在北京盛大开幕。大会由 ISC 互联网安全大会组委会、中国互联网协会、中国网络空间安全协会、全国工商联大数据运维(网络安全)委员会、中国人工智能学会、中国软件行业协会、中国企业联合会、360 互联网安全中心主办;中国通信企业协…