IT评测·应用市场-qidao123.com技术社区
标题:
Redis面经——Redis的双写一致性,一篇文章带你彻底搞懂什么是Redis的双写
[打印本页]
作者:
祗疼妳一个
时间:
2024-7-31 19:09
标题:
Redis面经——Redis的双写一致性,一篇文章带你彻底搞懂什么是Redis的双写
一、双写一致性概念
当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致
Redis的双写一致性,一样平常是基于两种场景,第一个是寻求强一致性,第二个允许延迟一致(包管数据的终极一致性)
二、包管双写一致性细节
寻求强一致性
(一)读操纵
缓存掷中,直接返回;缓存没有掷中则查询数据库,写入缓存,设定超时时间
(二)写操纵
延迟双删
那么题目来了,是先删除缓存呢还是先修改数据库呢?
1、先删除缓存,再操纵数据库
假设最开始缓存和数据库中的数据都是10条
有两个线程
(1)先删除缓存
(2)更新数据库数据
(3)查询缓存,缓存未掷中,则查询数据库,将数据写入到缓存中
但是这种方式还是会存在题目标!
请继续往下看
(1)线程1此时删除了缓存,由于线程的调理美满是由CPU来控制,此时线程1挂起,而线程2开始查询数据,此时线程2肯定是未掷中的状态,就去查询数据库,并将数据库更新前的数据又重新写入到缓存了
(2)此时,线程1开始执行,线程1完成了数据库的数据更新,数据库数据变成了20,但是此时的缓存中数据还是10,这就造成了脏数据的情况!!!
2、先操纵数据库,再删除缓存
1)正常的流程
假设初始缓存和数据库中的数据都是10
线程2开启,并直接更新了数据库,然后线程2删除了缓存。此时线程1查询缓存,发现缓存未掷中,直接去查询数据库,此时查询的数据是精确的,然后紧接着将数据库更新后的数据写到缓存中了。到此为止,数据还是一致性的
2)存在的题目
(1)假如此时缓存中的数据逾期了,那么线程1是拿不到数据的,直接查询数据库拿到一开始的10
(2)接下来线程2在线程1未同步到缓存前,先更新数据库,而且删除了缓存(此时缓存中key已颠末期,删不删除都是一样的),线程2成功将数据更新成了20,但是线程1开始执行,将一开始读取到的10写入到了缓存中,又总成了数据的不一致!
我们继续回到上面的题目
写操纵,要延迟双删
那么又有一个新的题目,就是为什么要删除两次缓存呢?
由于再次删除缓存,目标就是为了低落脏数据的风险
还又一个新的题目,为什么要延时删除呢?
由于数据库一样平常都是搭建主从集群的,以是要等候数据库的数据全部同步后开始删除缓存,否则还是会出现脏数据的情况。注意,这种方式没有绝对的一致性,延时多久不可预知,假如出现主从未完全同步时写入缓存,还是会导致脏数据
包管写操纵强一致性的方法!!!!重头戏!!!!!!
1、加入分布式锁,来控制
2、进阶版
由于一样平常写入到缓存中的数据都是读多写少的情况,这个时间我们就不用分布式锁了,直接利用读写锁!
详细的代码实现:
下面的读写代码,一定可以实现强一致性!但是性能就很低了!
(1)读操纵:
(2)写操纵:
注意读写锁的锁要保持一致
允许延迟一致(包管数据的终极一致性)
1、异步通知来包管数据的终极一致性
2、基于Canal的异步通知
canal是基于MySQL的主从同步来实现的
会监听主节点的binlog文件,binlog二进制文件中记载了所有的DDLH和DML语句,但是不包括数据查询,比如select大概show语句。
当文件发生更新了,那么就会通知缓存数据变更的情况。这种方式是对业务代码0侵入的,假如我们的业务场景中允许数据短暂延时,这种方式还是相对推荐的
至此,关于双写一致性的推演先容完毕,内容比较多,希望大家能够收藏反复学习,后续还会持续更新相干口试题,敬请期待!!!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/)
Powered by Discuz! X3.4