MySQL 与 Redis 缓存一致性的实现与挑战
缓存是缓存提高应用性能的重要手段之一,而 MySQL 和 Redis 是致性战两种常用的数据存储和缓存技术。在许多应用中,现挑常常将 Redis 用作缓存层,缓存以加速对数据的致性战访问。然而,现挑在使用 MySQL 和 Redis 组合时,缓存保持缓存与数据库之间的致性战一致性是一个不得不考虑的问题。

一、现挑缓存一致性的缓存挑战
MySQL 和 Redis 之间的缓存一致性涉及到两个方面:
1.数据一致性数据在 MySQL 和 Redis 中的一致性是指在对数据进行更新操作时,确保MySQL 和 Redis 中的致性战数据保持同步。如果 Redis 中的现挑缓存数据与 MySQL 数据库中的数据不一致,可能会导致应用程序出现错误以及一些未知的缓存问题。
2.缓存有效性缓存有效性是致性战指 Redis 中的缓存数据是否仍然有效,是源码库现挑否需要更新或者过期。如果 Redis 中的缓存数据过期,但 MySQL 中的数据已经更新,可能会导致从 Redis 中获取到的数据不准确。
再说实现缓存与数据库数据一致性的实现方法之前,我们先来了解一下什么是缓存模式?
直接往下看也可以,我在这篇文章里面会重新对几种缓存模式进行一下介绍,并加以配图说明。
二、缓存模式有哪些
如果你读过上面缓存模式那篇文章的话,相信你对缓存模式应该有一定的了解了,如果不了解也没关系,我们一起来看看吧。
1.Cache Aside最常用的缓存模式,大体意思是先从 cache 中取数据,没有获取到则从数据库中读取,成功后放到缓存中;
如果在 cache 中获取到数据直接返回;
更新时先把数据存到数据库,成功后再让缓存失效。

(1) 先更新数据库,再更新缓存
遇到的问题是两个并发的更新操作,数据库先更新的免费信息发布网后更新缓存,数据库后更新的先更新缓存,这样就会造成数据库与缓存的数据不一致,应用程序中读取的数据都是脏数据
(2) 先删除缓存,再更新数据库
遇到的问题是有两个并发操作,一个更新操作先删除了缓存,此时另一个并发的读取操作没有命中缓存,直接读取数据库并更新回了缓存,这个时候正好更新操作完成数据更新。此时数据库和缓存的数据不一致,应用程序读取的数据都脏数据了
(3) 先更新数据库,再删除缓存
这个方式也算是我们实际系统使用中比较推荐的一种方式,但是这种方式在理论上还是可能会出现问题,两个并发操作,其中一个查询操作没有命中缓存,此时查询出来了数据库中的老数据,此时另一个并发的更新操作,在刚才的亿华云并发读操作之后更新了数据库中的数据并删除了缓存,然后并发读操作线程又把老数据写入了缓存,此时又造成了数据的不一致,应用程序读取的都是脏数据。因为这种概率差生的情况实在是太小,所以才是我们系统中经常使用的一种方式了。
2.Read/Write ThroughCache Aside 模式中,应用程序需要维护两个数据存储,一个是缓存,一个是数据库,在 Read/Write Through 更新模式中,应用程序只需要维护缓存,数据库的维护工作就有缓存代理了
(1) Read Through
Read Through 模式就是在查询时更新缓存,也就是说,在缓存失效时,Cache Aside 模式是由调用方负责把数据载入缓存,而 Read Through 模式是缓存服务自己更新缓存,自己来加载数据。

当应用程序执行读操作时,如果缓存中不存在所需数据,则缓存会自动从数据源(如数据库)中读取数据,并将数据加载到缓存中,然后返回给应用程序。
Read-Through 策略减少了应用程序与数据源之间的直接交互次数,提高了读操作的性能和响应速度。
(2) Write Through
Write Through 和 Read Through 类似,当数据更新时,如果命中缓存则更新缓存,然后缓存更新数据库,这是一个同步的操作;如果没有命中缓存,直接更新数据库返回。

Write-Through 策略保证了缓存和数据源中的数据一致性,但由于每次写操作都需要等待数据源的确认,可能会影响写操作的性能和延迟。
3. Write Behind CachingWrite Behind Caching 更新模式是在更新数据时只更新缓存,不更新数据库,而我们的缓存会异步的更新数据库。这个模式的话就是速度快,毕竟我们直接操作内存,因为是异步的,Write Behind Caching 更新模式还可以合并对同一个数据的多次操作到数据库,所以性能的提升也是很明显的
问题就是数据不是强一致性的,而且还可能会丢失,Write Behind Caching 更新模式实现逻辑复杂,因为它需要确认有哪些数据是被更新的,哪些数据是需要刷到持久层的数据库的。只有当缓存失效的时候才会把它真正的持久化起来。

Write-Behind 策略提高了写操作的性能和响应速度,但在写入缓存后,数据源中的数据可能会落后于缓存中的数据一段时间,存在一定的数据一致性风险。
三、一致性有哪些

说到一致性,我们应该想到的就是分布式系统中多个节点对看到的数据副本都保持一致的特性。换个说法就是,无论用户在哪个节点上执行操作,最终所有节点上的数据是相同的,且满足一定的约束条件。
在分布式系统中,实现一致性是很困难的,因为系统中的多个节点可能会因为网络延迟,节点故障或者其他的因素导致多个数据副本之间的状态不一致。为了实现分布式系统中的一致性,业界常用的算法和协议有 Paxos、Raft、ZAB。
分布式系统的一致性又分为强一致性、弱一致性、最终一致性。
强一致性:最严格的一致性,相当于对于用户来说是最友好的。因为这个相当于系统写入的是什么数据,读取时也就是什么数据。弱一致性:相比于强一致性,弱一致性不承诺立即读取最新的值,也不承诺多久之后数据一致。但是会尽可能的保证在到达某个时间点之后,数据达到一致状态。最终一致性:最终一致性是弱一致性的一个特例,保证在一定时间之后达到数据一致状态,因此最终一致性也是目前业界来说最推崇的模型。四、一致性实现方法
1.双写双写其实就是 Write Through 模式,在写入 MySQL 数据库的同时,立即写入 Redis 缓存。这样可以确保 MySQL 和 Redis 中的数据保持一致,但增加了写入的延迟,并且增加了系统复杂度。
(1) 双写为什么先操作数据库在操作缓存?
我们来看如下的例子,线程A 与 线程B 是一组并发请求。

到这就发现了问题了吧,如果你没发现,那就跟着我的思路来看一下。
大家来看第三步,线程B 去读取数据库,此时 线程A 是还没有写入新数据的,所以此时 线程B 读取的数据是老数据。
而第5步,线程A 往数据库写入的才是最新的数据。
所以此时也就造成了数据不一致 了。
对于这种情况造成的脏数据缓存,有的小伙伴可能就提出来了,可以使用缓存双删啊,那么我们来继续往下看。
(2) 缓存延迟双删

延迟双删,就是字面意思,删除两边缓存。你知道问题在哪吗,想一想?
。。。。。。
双删,有可能删除失败吗?
删除失败怎么办?
双删的步骤如下:
删除缓存。更新数据库。延迟删除(此时延迟的差不多是读请求的耗时多一点,防止读请求设置脏数据缓存)。(3) 删除缓存的重试机制
删除缓存失败,第一个想到的应该是,删除失败了就多删除几次吧。
所以我们可以借助于消息队列,将删除失败的 key 加入到消息队列,对消息进行重试删除操作。

既然我们都用到消息队列了,那么我们为什么不直接监听 binlog 实现异步删除缓存呢。
2.消息队列使用消息队列监听数据库变更事件、异步更新缓存。能够保证在数据库更新后,缓存能够按照顺序进行更新。

此时的例子就是,使用 Canal 监听 binlog ,发送数据到 MQ 中,应用程序监听 MQ 消息实现 Redis 缓存的更新。
五、总结
实现 MySQL 与 Redis缓存的一致性中,需要考虑很多的方面,最直观的就是业务场景,性能要求,以及数据的安全等因素综合考虑。
例如,对于读多写少的场景,可以采用 Read/Write Through 模式;
而对于写操作频繁的场景,则可能需要考虑 Write Behind Caching 模式。
相关文章
联想电脑账户密码错误的原因及解决方法(探索联想电脑账户密码错误的背后问题,教你轻松解决困扰)
摘要:在日常使用联想电脑的过程中,我们经常会遇到账户密码错误的情况,无论是忘记密码还是输入错误都会造成一定的困扰。本文将从密码错误的原因出发,为你详细介绍如何解决这个问题。一、复...2025-11-04
7月份GitHub上最热门的JavaScript开源项目排行已经出炉啦,一起来看看上榜详情吧!1. reacthttps://github.com/facebook/react Star 1531742025-11-04
我们变成纸片人会是什么样?被玩坏的AR软件,成了应用榜单第一名
RakugakiAR 可以让你的任何纸片人老婆进入三次元但还是纸片人)。「跃然纸上」通常用来形容一个人文笔生动,但最近,一款风靡世界的 APP 似乎重新定义了这个词:它真的可以让你笔下的内容从纸上跳出2025-11-04
HashMap加载因子为什么是0.75?转化红黑树阈值为8?
正文加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。对于使用链表法的散列表来说,查找一个元素的平均时间2025-11-04常见的电脑设置错误及解决方法(避免电脑设置错误的关键注意事项)
摘要:在现代社会中,电脑已经成为人们工作和生活中不可或缺的一部分。然而,许多人在使用电脑时常常遇到各种设置错误,导致电脑功能无法正常发挥。本文将探讨一些常见的电脑设置错误以及解决方法,帮...2025-11-04
介绍最近看了一下Dubbo的源码,国人写的框架和国外的果然是两种不同的风格,Dubbo的源码还是比较清晰容易懂的。Spring框架一个Bean的初始化过程就能绕死在源码中.Dubbo的架构是基于分层来2025-11-04

最新评论