Redis 和 MySQL 如何保证数据一致性?
我们都知道,和L何在开发过程中,保证很多时候都会用到我们的数据缓存,而缓存的致性种类也是五花八门的,我们今天来了解的和L何就是关于缓存中的一种,那就是保证 Redis。
Redis
redis是数据一个key-value存储系统。
和Memcached类似,致性它支持存储的和L何value类型相对更多,包括string(字符串)、保证list(链表)、数据set(集合)、致性zset(sorted set --有序集合)和hash(哈希类型)。和L何
这些数据类型都支持push/pop、保证add/remove及取交集并集和差集及更丰富的数据操作,而且这些操作都是原子性的。
在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,b2b信息网数据都是缓存在内存中。
区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
今天我们不说这个 Redis 的主从同步,我们来说说我们最常使用 Redis 的时候,会导致的一些问题。
Redis和 Mysql 如何保持一致
说到这个一致性,了不起就得和大家说道说道了,为什么会出现这种情况呢?实际上就是和 Redis 的使用有很大的关系。
都知道,Redis 是一个 NoSQL 的数据库,而且他还很快,所以很多数据都会从 Mysql 中把数据取出来,然后放到我们的缓存中,然后下次读取数据的时候,从 Redis 中直接去读取,这个时候,云服务器提供商我们就会出现问题了。
什么问题呢?
在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。所以,就需要使用redis做一个缓冲操作,让请求先访问到Redis,而不是直接访问MySQL等数据库。
这个业务场景,主要是解决读数据从Redis缓存,一般都是按照下图的流程来进行业务操作。

读取缓存步骤一般没有什么问题,但是一旦涉及到数据更新:数据库和缓存更新,就容易出现缓存Redis和数据库MySQL间的数据一致性问题。
不管是先写 MySQL数据库,再删除Redis缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。
举一个例子:
1.如果删除了缓存 Redis,还没有来得及写库 MySQL,另一个线程就来读取,发现缓存为空,网站模板则到数据库中读取数据,写入缓存,此时缓存中为脏数据。
2.如果先写了库,在删除缓存前,写库的线程宕机了,没有删除掉缓存,则也会出现数据不一致情况。
因为写和读是并发的,没法保证顺序,就会出现缓存和数据库的数据不一致的问题。
其实解决方案也有不是少,今天了不起来给大家分析一下 Redis 和 Mysql 保证数据一致性的实现方案。
缓存和数据库一致性解决方案
延时双删策略
延时双删策略步骤如下:
1.先删除缓存2.再写数据库3.休眠N毫秒4.再次删除缓存其实我们可以来想一下,如果有三个线程,分别是 线程1 ,线程2,线程3,三个线程,
其中,线程1先删除缓存;
线程2读取缓存为null,同步db数据到缓存中;
线程1更新db中的数据;
线程3查询缓存中数据是旧数据;
这样的话,就会出现 Mysql 和 Redis 中的数据不一致,这时候采用延迟双删策略,去保证数据的一致性,
这时候就有人问了,为什么要休眠一段时间,然后再执行呢?
假象一下,如果没有第三步操作时,有很大概率,在两次删除Redis操作执行完毕之后,数据库的数据还没有更新,此时若有请求访问数据,便会出现我们一开始提到的数据不一致的问题。
为什么还要再次删除缓存呢?
如果我们没有第二次删除操作,此时有请求访问数据,有可能是访问的之前未做修改的 Redis 数据,删除操作执行后,Redis为空,有请求进来时,便会去访问数据库,此时数据库中的数据已是更新后的数据,保证了数据的一致性。
因为感觉这种延迟双删除可靠性并没有那么高,因为我们并不能保证删除 Redis 成功,也不能保证数据库更新也是成功的,也就是我们所说的原子性,两个组合起来只是在理想情况下。
比如双删失败我们应该怎么处理呢?
1、设置缓存过期时间从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案。所有的写操作以数据库为准,只要到达缓存过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存。
结合双删策略+缓存超时设置,这样最差的情况就是在超时时间内数据存在不一致。
2、重试方案重试方案有两种实现,一种在业务层做,另外一种实现中间件负责处理。
然而,该方案有一个缺点,对业务线代码造成大量的侵入。
流程如下:
1.更新数据库数据;
2.缓存因为种种问题删除失败;
3.将消费消息,获得需要删除的key;
4.自己消费消息,获得需要删除的key;
5.重试删除操作,直到成功。
而这个放在业务层去处理的话,侵入太高,所以一般是不太推荐使用来解决这个问题。
但是呢,还有一个就是使用中间件来进行处理。
启动一个订阅程序去订阅数据库的binlog,获得需要操作的数据。在应用程序中,另起一段程序,获得这个订阅程序传来的信息,进行删除缓存操作。
流程如下:
1.更新数据库数据;
2.数据库会将操作信息写入binlog日志当中;
3.订阅程序提取出所需要的数据以及key;
4.另起一段非业务代码,获得该信息;
5.尝试删除缓存操作,发现删除失败;
6.将这些信息发送至消息队列;
7.重新从消息队列中获得该数据,重试操作。
关于延迟双删除策略,你学会了么?
相关文章
电脑C盘满了怎么删除没用的东西?(解决电脑C盘存储问题的实用方法)
摘要:随着时间的推移,电脑的C盘存储空间逐渐变得紧张。当C盘满了之后,电脑的性能和速度都会受到影响。了解如何删除没用的东西以释放C盘空间是非常重要的。本文将为您介绍一些实用的方法来解决这...2025-11-04
面试官:count(*)、count1(1)、count(主键)、count(字段) 哪个更快?
大家好,我是君哥。使用SQL时,统计表数据量是经常遇到的需求,比如在商品页面展示商品库存量。统计表数据量的方法有count(*)、count1(1)、count(主键 id)、count(字段)。那这2025-11-04- 在“数字中国”战略的磅礴浪潮之下,网络安全已然跃升为维系国家经济命脉、社会稳定和公民隐私安全的战略基石。然而,随着人工智能AI)、大数据技术在国内快速发展,数据作为核心生产要素的战略地位凸显,同时,国2025-11-04
 CMU15-445 数据库系统播客:海量数据场景下的分布式 OLAP
在数据如潮水般涌来的今天,如何从PB级的历史数据中高效地挖掘商业洞见,已成为企业在激烈竞争中脱颖而出的关键。在线分析处理OLAP)数据库系统正是为此而生。它并非为处理高并发的日常交易OLTP)而设计,2025-11-04苹果平板电脑恢复错误解决指南(解决苹果平板电脑恢复错误的有效方法和技巧)
摘要:苹果平板电脑作为一款功能强大的移动设备,常常被用于工作和娱乐。然而,在使用过程中,有时会遇到恢复错误的情况,导致系统无法正常运行。本文将分享一些有效的方法和技巧,帮助您解决苹果平板...2025-11-04
持续的医疗进步意味着,与相对较近的过去相比,人们有更多的机会活得更健康、更长寿。即便如此,人们几十年前第一次听到的许多保持健康的建议今天仍然适用。比如吃大量的水果和蔬菜,定期锻炼,每年进行体检,并将压2025-11-04

最新评论