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

news/2025/2/9 3:02:56 标签: 数据库, redis, 缓存

一 什么是双写一致性?

当修改了数据库(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.niftyadmin.cn/n/5845468.html

相关文章

如何获取sql数据中时间的月份、年份(类型为date)

可用自带的函数month来实现 如: 创建表及插入数据: create table test (id int,begindate datetime) insert into test values (1,2015-01-01) insert into test values (2,2015-02-01) 执行sql语句,获取月份: select MONTH(begindate)…

初窥强大,AI识别技术实现图像转文字(OCR技术)

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据、人工智能领域创作者。目前从事python全栈、爬虫和人工智能等相关工作,主要擅长领域有:python…

Vue中el-table定义单元格底色的几种方式

1. 使用 row-class-name 属性 这种方式可以为整行设置样式类&#xff1a; <template><el-table :data"tableData" :row-class-name"tableRowClassName"><!-- 表格列定义 --></el-table> </template><script> export…

计算机网络笔记再战——理解几个经典的协议6——TCP与UDP

目录 先说端口号 TCP 使用序号保证顺序性和应答来保证有效性 超时重传机制 TCP窗口机制 UDP 路由协议 协议分类&#xff1a;IGP和EGP 几个经典的路由算法 RIP OSPF 链路状态数据库&#xff08;LSDB&#xff09; LSA&#xff08;Link State Advertisement&#xff0…

全网多平台媒体内容解析工具使用指南

一、工具特性概述 近期体验了一款基于Web端的多媒体解析服务&#xff0c;该平台通过技术创新实现跨平台内容解析功能&#xff0c;主要特点如下&#xff1a; 1.1 跨平台支持 兼容主流社交媒体&#xff1a;Bilibili、YouTube、Twitter、Instagram等 支持短视频平台&#xff1a…

2025 IT职业发展方向及推荐

一、云计算与DevOps&#xff08;推荐指数&#xff1a;★★★★★&#xff09; 推荐理由&#xff1a; 市场需求&#xff1a; 据Gartner报告&#xff0c;2025年全球公有云市场规模将突破8300亿美元&#xff0c;但混合云管理人才缺口达400万&#xff08;IDC数据&#xff09;。 企…

5.【BUUCTF】[BJDCTF2020]Easy MD5及知识点

进入题目页面如下 尝试提交XSS攻击以及sql注入 并没有回显&#xff0c;尝试无果&#xff0c;用burp suite抓取响应包查看一下&#xff0c;右键→拦截→拦截响应 在响应中找到了响应头 Hint&#xff1a;select * from ‘admin’ where password md5($pass,ture) 给出提示MD5 SQ…

文件上传到腾讯云存储、签名及设置过期时间

将文件上传到腾讯云对象存储&#xff08;COS&#xff0c;Cloud Object Storage&#xff09;可以通过腾讯云提供的 SDK 实现。以下是详细的步骤和示例代码&#xff0c;帮助您完成文件上传操作。 步骤 注册腾讯云账号并创建存储桶&#xff1a; &#xff08;1&#xff09;登录腾讯…