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侵入的,如果我们的业务场景中允许数据短暂延时,这种方式还是相对推荐的

至此,关于双写一致性的推演介绍完毕,内容比较多,希望大家能够收藏反复学习,后续还会持续更新相关面试题,敬请期待!!!

  • 38
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Redis双写一致性问题是指在使用Redis集群时,当进行写操作时,由于数据的复制存在一定延迟,可能会导致数据不一致的情况。这种情况在以下场景中尤为常见: 1. 主节点写入后,备份节点尚未完成复制:当主节点执行写操作后,备份节点需要一定时间才能完成数据的复制。在这段时间内,如果主节点宕机或者网络发生故障,备份节点可能无法完全复制数据,导致数据不一致。 2. 主节点写入后,备份节点复制过程中失败:备份节点在复制数据过程中也可能发生故障,例如网络中断或者节点故障。这样一来,主节点写入的数据将无法正确复制到备份节点上,导致数据不一致。 为了解决Redis双写一致性问题,可以采取以下几种措施: 1. 使用Redis Sentinel:Redis Sentinel是Redis提供的高可用性解决方案,通过监控和自动故障转移来确保Redis集群的可用性。当主节点发生故障时,Sentinel会自动选举新的主节点,并将写操作重定向到新的主节点上,从而保证数据的一致性。 2. 使用Redis Cluster:Redis Cluster是Redis提供的分布式解决方案,它将数据分片存储在多个节点上,通过数据分片和复制机制来提供高可用性和数据一致性。在Redis Cluster中,每个主节点负责多个槽位的数据,备份节点会自动复制主节点的数据,确保数据的一致性。 3. 使用同步复制:在一些特定场景下,可以使用Redis的同步复制机制来提高数据的一致性。同步复制会等待所有备份节点都完成复制后才返回写操作的成功响应,确保所有节点都有相同的数据。 需要注意的是,以上措施可以提高Redis的数据一致性,但并不能完全解决所有情况下的数据不一致问题。在一些极端情况下,例如网络分区、多节点同时故障等,可能仍然存在数据不一致的可能性。因此,在设计应用程序时,需要根据实际需求和业务场景来选择适当的解决方案,并进行必要的数据容错和异常处理。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Be explorer

若认可笔者文章,手头富裕望支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值