IT评测·应用市场-qidao123.com
标题:
MySQL与Redis的缓存同等性问题
[打印本页]
作者:
玛卡巴卡的卡巴卡玛
时间:
2025-3-14 23:09
标题:
MySQL与Redis的缓存同等性问题
MySQL与Redis的缓存同等性问题
前言
在学习中,为了提高数据的读取效率,我们每每会利用Redis来作为MySQL数据的缓存,那么,天然就产生了二者间数据的同等性问题。
想要对MySQL和Redis进行数据处置惩罚,天然会产生以下问题:
MySQL与Redis操作的时序问题
更新与删除的选择实时序问题
下面我们来一一分析:
先操作MySQL
先删除MySQL中数据
这种情况下,当我们选择先将MySQL中的数据删除时,如果后续写入新数据失败,新数据就很有可能会丢失,我们就完全失去了这条数据,这是难以接受的。以是我们还是来看看先更新MySQL的情况吧:
先更新MySQL中数据
这种情况下,当客户端修改一个数据时,我们先将MySQL中数据更新为最新状态,然后再操作Redis(如果第一步更新MySQL数据失败,就不会继续操作Redis了,此时MySQL和Redis中的数据都还是老数据,也是处于同等状态,可以接受):
再更新Redis中数据
试想如许一种情况:
线程A和线程B按以下次序实行:
线程A缓存未命中,然后从MySQL中读到数据c=1
线程B想将数据c=1修改为c=2
线程B先更新MySQL成功,再更新Redis数据c=2(岂论更新Redis成功与否)
线程A写回Redis数据c=1
可以看到,此时MySQL中是新数据c=2,Redis中却是老数据c=1,处于不同等状态。在Redis中该数据自动过期,大概再次更新该数据之前,客户端都会读到Redis中的老数据(脏数据)。
不过读操作,每每比写操作更快速,也就是说大多数情况下,线程A等线程B操作完了再写回Redis的情况不会出现。
但是,对于并发更新的情况,可能会出现多个线程并发更新Redis数据,导致老数据覆盖新数据的情况,也会造成不同等状态。
再删除Redis中数据
与上面“再更新Redis中数据”的情况类似,可能会出现线程B删除完Redis数据后,线程A又写回老数据的情况。
但是,对于并发更新的情况,就算多个线程并发删除Redis数据,也能够包管删除老数据,不会造成不同等状态。
当然,如果删除Redis失败了,Redis中还是会留下老数据,造成不同等状态。
先操作Redis
先删除Redis中数据
再更新MySQL中数据
试想如许一种情况:
线程A和线程B按以下次序实行:
线程B想将数据c=1修改为c=2
线程B先删除Redis中数据成功
线程A缓存未命中,然后从MySQL中读到数据c=1
线程B更新MySQL中数据c=2
线程A写回Redis数据c=1
可以看到,此时MySQL中是新数据c=2,Redis中却是老数据c=1,处于不同等状态。在Redis中该数据自动过期,大概再次更新该数据之前,客户端都会读到Redis中的老数据(脏数据)。
别的,对于并发更新的情况,可能会出现多个线程并发更新MySQL数据,导致老数据覆盖新数据的情况,也会造成不同等状态。
再删除MySQL中数据
这种情况下,当我们选择将MySQL中的数据删除时,如果后续Redis中的新数据丢失(磁盘存储相对内存存储的可靠性更高),我们就完全失去了这条数据,这是难以接受的。
总结
Cache-Aside (旁路缓存)
综上所述,我们每每会选择
先更新MySQL中数据-再删除Redis中数据
的方案。
以上所述所有的方案,有一个统称:
Cache-Aside (旁路缓存)
。
直读 与 同步/异步直写
别的,如果我们将缓存的业务直接从其它业务代码中抽取出来,给其它业务提供一个缓存抽象层,将缓存的操作全部放在这个缓存抽象层中独立存在,也就是缓存的解耦。
如许,主体业务就只必要与抽出来的缓存层进行交互,无需再关心数据的同等性,直接读/写缓存层,也就是
直读
与
直写
。
直读(Write-Through)
客户端(也可以是其他业务层)直接读取Redis缓存,如果缓存未命中,从MySQL中读取数据后,再写回Redis,然后再返回给客户端。
直写(Write-Through)
客户端(也可以是其他业务层)直接先更新Redis缓存,然后再更新MySQL,然后再返回数据给客户端。
上面的是
同步直写
,如果在更新MySQL的同时,异步将数据返回给客户端,那么就叫
异步直写(Write-Behind)
。
canal
别的,为了提高体系的可用性,我们可以共同一些成熟的中间件,例如:
利用Canal监控MySQL的binlog日记,自动通知缓存业务MySQL中的数据进行了什么修改,可以让我们的体系迅速知道MySQL的数据改动,耽误极低。
在缓存业务中,我们每每还可以引入
消息队列
,提高数据传输的可靠性,例如:
当Canal监控到MysQL数据改动后,将监控数据发送到RabbitMQ,由订阅了相干Topic的缓存业务消费监控数据并进行处置惩罚,可以有效避免数据传输中失败、丢失等问题。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/)
Powered by Discuz! X3.4