Redis双写一致性(数据库与redis数据一致性)

news2025/4/21 16:45:16

一 什么是双写一致性?

当修改了数据库(MySQL)中的数据,也要同时更新缓存(redis)中的数据,缓存中的数据要和数据库中的数据保持一致

双写一致性,根据业务对时间上的要求,可以分为三种情况:

1、延时双删:较为准时的一致性,Redis中的数据和MySQL较为准时的一致,不会超过很长的时间

2、redissson锁:保证强一致性;准时

3、异步写入redis:如果业务允许短暂时间内redis与MySQL数据库中数据的不一致,但是保持最终一致的情况;

二 延时双删

2.1 延时双删的背景

背景:当数据库中的数据出现了变化,我是应该先删除缓存中的数据,还是先修改数据库中的数据,再删除缓存中的数据呢?

其实不管是先删除redis中的数据,还是先update数据库中的数据,都会导致数据不一致的问题

第一种情况:先删除Redis缓存,再更新MySQL数据库

当线程1删除了缓存,尚未更新数据库时,线程2进来了,查询redis中,没有这条数据,未命中,那么线程2会去查询数据库,并将结果写入缓存中;这时候线程1才会更新数据库的数据;

如图中的redis缓存中,还是原来的数据10,数据库以及改成了20,且由于redis中有数据,所有后续的线程不会再去查询数据库更新数据,这就导致了脏数据的产生

第二种情况:先操作MySQL数据库,再更新Redis

如果线程1去查询redis缓存的时候,Redis中的该条数据以及过期了,然后去查询数据库,尚未写入缓存时,线程2更新了数据库,再删除缓存;删除了缓存之后,线程1此时再获得CPU资源,去Redis中写入数据(这时候线程1拿着的还是老数据),也会导致Redis中和MySQL中的数据不一致

虽然这两种情况很少出现,但是一旦出现,就有可能对业务造成重大损失,是不可容忍的!

2.2 什么叫延时双删

就是上述背景两个方式的集合,先删除Redis中的数据,在更新MySQL数据库中的数据,最后再次删除Redis中的数据;至于延时

为什么要延时呢?

现在大部分业务的数据库,都是主从集群的数据库;修改数据库之后,如果立马删除Redis中的数据,主库的数据尚未同步到从库,而后续有其他线程从从库中查询到尚未同步过来的数据写入redis,还是会导致脏数据的风险,所以要延时(可以用定时器,或延时队列等)再删除一次redis中的数据

注:由于你是无法绝对确认什么时候数据库进行主从同步的,所以哪怕你延时了,还是有可能在数据库同步之前删掉Redis,然后其他线程获取脏数据导致不一致的情况的!所以延时双删,无法保证强一致性

三 redisson锁

如果业务必须要求,保持Redis和MySQL数据库中的数据,实时的强一致性,那么我们可以使用分布式锁,和redisson提供的读写锁来保证数据的同步

3.1分布式锁(互斥锁)

如图所示,给资源加上一个互斥锁:当线程1要更新MySQL数据库和删除Redis中的数据前,加互斥锁,这样其他线程无法获取Redis中的数据,只能等线程1写入MySQL,并删除缓存完成释放锁后,才能读取数据;

但是很明显,这样的互斥锁虽然保证了强一致性,但是性能很低,充斥大量的获取锁和释放锁的额外开销

3.2 共享锁和排他锁

由于我们的现实情况中,对Redis中的数据,肯定是读多写少的;所以没必要使用互斥锁

这时我们可以使用redisson提供的共享锁和排他锁

当某一个线程要更新MySQL和删除Redis中的数据时,就必须先获得排他锁(其他线程无法读)这样删除完成后,其他线程才能获取共享锁以读取数据

代码实现参考如下:

使用共享锁的优缺点:

优点:强一致性

缺点:还是性能低,只比互斥锁强

四 异步写入redis

当业务不要求redis中的数据,立马从MySQL中同步出来时,我们就可以使用异步的方式来实现双写一致性了,这样既没有性能问题,也保证了双写一致性

4.1异步通知

当更新了MySQL中的数据,需要写入redis时,可以发送一个异步消息,放到MQ中,由专门的消费者去写入redis中

4.2 canal

canal是阿里巴巴出的一种中间件,基于MySQL的主从同步来实现的:

当有数据写入数据库,数据库进行主从同步时,会把所有ddl和dml的语句记录到一个binlog文件中;

而canal的作用就是伪装成一个MySQL的从节点,去监听这个binlog日志,把MySQL中我们监听的数据的变化,异步通知给缓存服务,进行写入redis中

canal的优点是:对业务代码几乎无侵入,前文中的方式多多少少对代码都有侵入,而且速度很快

写在后面:

其实,我们公司的真实方式,并不是写入MySQL后,删除redis的数据,再由下一个线程查询MySQL写入redis;

而是,直接写入MySQL后,再立马直接更新写入redis中,按我的理解,这样的方式很直接,很有效,既保证了时效性,也保证了强一致性,并没有什么缺点;

如果有大佬看到这篇文章,烦请可以给我解释一下,我们公司的这样操作的缺点是什么,感激不尽

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

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

相关文章

14.PPT:中国注册税务师协会宣传【26】

目录 NO12 NO3/4/5​ NO678​ 【文本框水平/垂直居中】【文本框内容水平/垂直居中】 NO12 坑:注意❗Word文档的PPt素材.docx的标题大纲是混乱的,虽然他设置了,所以我们需要重新设置 设计→主题视图→幻灯片母版→删除版式插入logo NO3/4…

搭建Golang gRPC环境:protoc、protoc-gen-go 和 protoc-gen-go-grpc 工具安装教程

参考文章: 安装protoc、protoc-gen-go、protoc-gen-go-grpc-CSDN博客 一、简单介绍 本文开发环境,均为 windows 环境,mac 环境其实也类似 ~ ① 编译proto文件,相关插件 简单介绍: protoc 是编译器,用于将…

autMan奥特曼机器人-对接deepseek教程

一、安装插件ChatGPT 符合openai api协议的大模型均可使用此插件,包括chatgpt-4/chatgpt-3.5-turbo,可自定义服务地址和模型,指令:gpt,要求Python3.7以上,使用官方库https://github.com/openai/openai-pyt…

数据分析:企业数字化转型的金钥匙

引言:数字化浪潮下的数据金矿 在数字化浪潮席卷全球的背景下,有研究表明,只有不到30%的企业能够充分利用手中掌握的数据,这是否让人深思?数据已然成为企业最为宝贵的资产之一。然而,企业是否真正准备好从数…

Spring Web MVC项目的创建及使用

一、什么是Spring Web MVC? Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中,通常被称为Spring MVC。 1.1 MVC的定义 MVC 是 Model View Controller 的缩写,它是软件工程中的一种软件架构…

MySQL的底层原理与架构

前言 了解MySQL的架构和原理对于很多的后续很多的操作会有很大的帮助与理解。并且很多知识都与底层架构相关联。 了解MySQL架构 通过上面的架构图可以得知,Server层中主要由 连接器、查询缓存、解析器/分析器、优化器、执行器 几部分组成的,下面将主要…

Node.js 实现简单爬虫

介绍 爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。 本文将使用 Nodejs 编写一个简单的爬虫脚本,爬取一个美食网站,获取菜品的标题和图片链接,并以表格的形式输出。 准备工作 1、初始化项目 首先&#xff0…

2024.1版android studio创建Java语言项目+上传gitee

1.在gitee上创建仓库 Gitee 创建仓库并邀请成员指南_gitee创建仓库邀请成员-CSDN博客 见1 2.新建android studio项目 3.在Android studio配置gitee Android Studio提交代码到gitee仓库_android log in to gitee-CSDN博客 其中的一二步 p.s.添加gitee账户选择password时&a…

opentelemetry-collector 配置elasticsearch

一、修改otelcol-config.yaml receivers:otlp:protocols:grpc:endpoint: 0.0.0.0:4317http:endpoint: 0.0.0.0:4318 exporters:debug:verbosity: detailedotlp/jaeger: # Jaeger supports OTLP directlyendpoint: 192.168.31.161:4317tls:insecure: trueotlphttp/prometheus: …

SQL Server 数据库迁移到 MySQL 的完整指南

文章目录 引言一、迁移前的准备工作1.1 确定迁移范围1.2 评估兼容性1.3 备份数据 二、迁移工具的选择2.1 使用 MySQL Workbench2.2 使用第三方工具2.3 手动迁移 三、迁移步骤3.1 导出 SQL Server 数据库结构3.2 转换数据类型和语法3.3 导入 MySQL 数据库3.4 迁移数据3.5 迁移存…

C# SQlite使用流程

前言 不是 MySQL 用不起,而是 SQLite 更有性价比,绝大多数的应用 SQLite 都可以满足。 SQLite 是一个用 C 语言编写的开源、轻量级、快速、独立且高可靠性的 SQL 数据库引擎,它提供了功能齐全的数据库解决方案。SQLite 几乎可以在所有的手机…

MySQL数据库 (三)- 函数/约束/多表查询/事务

目录 一 函数 (一 字符串函数 (二 数值函数 (三 日期函数 (四 流程函数 二 约束 (一 概述 (二 约束演示 (三 外键约束 三 多表查询 (一 多表关系 1 一对多(多对一) 2 多对多 3 一对一 (二 多表查询概述 (三 内连接 1 查询语法 2 代码实…

【玩转 Postman 接口测试与开发2_018】第14章:利用 Postman 初探 API 安全测试

《API Testing and Development with Postman》最新第二版封面 文章目录 第十四章 API 安全测试1 OWASP API 安全清单1.1 相关背景1.2 OWASP API 安全清单1.3 认证与授权1.4 破防的对象级授权(Broken object-level authorization)1.5 破防的属性级授权&a…

攻防世界baigeiRSA

打开题目附件 import libnum from Crypto.Util import number from secret import flagsize 128 e 65537 p number.getPrime(size) q number.getPrime(size) n p*qm libnum.s2n(flag) c pow(m, e, n)print(n %d % n) print(c %d % c)n 8850300144784503160345704866…

[NKU]C++安装环境 VScode

bilibili安装教程 vscode 关于C/C的环境配置全站最简单易懂!!大学生及初学初学C/C进!!!_哔哩哔哩_bilibili 1安装vscode和插件 汉化插件 ​ 2安装插件 2.1 C/C 2.2 C/C Compile run ​ 2.3 better C Syntax ​ 查看已…

Node.js 环境配置

什么是 Node.js Node.js 是一个基于 Chrome V8 JavaScript 引擎的 JavaScript 运行时环境,它允许你在服务器端运行 JavaScript。传统上,JavaScript 主要用于浏览器中的前端开发,而 Node.js 使得 JavaScript 也能够在服务器上执行,…

1Panel应用推荐:WordPress开源博客软件和内容管理系统

1Panel(github.com/1Panel-dev/1Panel)是一款现代化、开源的Linux服务器运维管理面板,它致力于通过开源的方式,帮助用户简化建站与运维管理流程。为了方便广大用户快捷安装部署相关软件应用,1Panel特别开通应用商店&am…

DMZ区的作用和原则

DMZ(Demilitarized Zone,非军事化区)是网络安全架构中一个重要的概念,其主要作用和原则如下: DMZ的作用 隔离风险 DMZ作为内外网络之间的缓冲区,能够有效隔离外部网络的攻击风险。将对外提供服务的服务器&…

如何将本地 Node.js 服务部署到宝塔面板:完整的部署指南

文章简介: 将本地开发的 Node.js 项目部署到线上服务器是开发者常见的工作流程之一。在这篇文章中,我将详细介绍如何将本地的 Node.js 服务通过宝塔面板(BT 面板)上线。宝塔面板是一个强大的服务器管理工具,具有简洁的…

4.3 线性回归的改进-岭回归/4.4分类算法-逻辑回归与二分类/ 4.5 模型保存和加载

4.3.1 带有L2正则化的线性回归-岭回归 岭回归,其实也是一种线性回归,只不过在算法建立回归方程的时候1,加上正则化的限制,从而达到解决过拟合的效果 4.3.1.1 API 4.3.1.2 观察正则化程度的变化,对结果的影响 正则化力…