如果保证redis数据一致性

1,读取数据
当线程读取数据时不会发生数据变化
2,读写
解决流程无非下面几种怎么选择呢:
先 更新缓存 再 更新数据库
先 删除缓存 再 更新数据库
先 更新数据库 再 更新缓存
先 更新数据库 再 删除缓存 (数据库指存储数据的mysql,缓存是redis里的数据)

选择方法
在这里插入图片描述
与其更新缓存不如直接删除更新成本高,直接删除缓存,修改数据库,当第二次访问redis拿数据如果没有,就会访问musql并且把数据缓存到redis中。
一,那先操作缓存还是操作数据库呢
在这里插入图片描述
先操作redis再修改数据库:线程1发出修改,先把redis删除了再去修改mysql,此时线程2在发现redis没有数据,去找数据库,但是数据库是老数据,线程A还没完成。这样redis又存入了老数据。只能到redis过期时间到了,才能查到新数据。

解决办法就是:每次mysql中数据更新之后删除一次redis中数据 *** 这就是双删**

但是线程2可能会有一次数据不一致。 解决就是保证强一致性,就是保证redis与mysql是原子性的,使用分布式锁可以实现但是影响系统并发性贼菜,一般保证最终一致性,而不是选择强一致性

第二次删除要延迟好比几百毫秒,应为万一线程A写数据太快而B已经拿到老数据会覆盖缓存中的新数据*** 也就是常说的 延迟双删

二,当先操作数据库在操作缓存
在这里插入图片描述
当线程1修改数据库未删除redis中数据,其他线程拿到脏数据,也能保证最终一致。
这种办法主要问题是在极端情况下修改完数据库删除redis失败了,redis数据就一直是脏数据知道失效
解决办法:删除重试,可以借用Mq,如果删除失败发送异步请求到mq,然后mq通知客户端重新删除redis.
在这里插入图片描述
但是这样代码耦合度高
解耦办法;使用另一款组件canal,原理读取binlog异步删除,(数据库实现主从复制也是通过读取binlog)
就是如果有数据变动会通知canal,然后canal客户端(监听canal的springboot应用)完成缓存更新
在这里插入图片描述

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值