Redis分布式缓存

本文讨论了Redis作为分布式缓存时遇到的一致性问题,包括数据更新、缓存穿透和缓存击穿。提出了解决方案,如延迟双删、异步处理和使用布隆过滤器。推荐方案强调先更新数据库再删除缓存,以及应对可能的异常情况如mq重试。
摘要由CSDN通过智能技术生成

一、使用Redis作为分布式缓存存在的问题
        1、数据的一致性问题:即Redis缓存服务器与mysql之间存在数据不一致问题
一般情况下,新增数据没有一致性的问题,修改和删除数据会有一致性问题
因为市面上的解决方案都是不去更新缓存,而是删除缓存,再更新缓存,所以新增不存在一致性问题;

        2、数据一致性产生的原理:

线程A执行删除缓存---》删除成功 -------》线程A执行更新数据库操作
线程B查询缓存 --- 》发现缓存为空 ---》线程B执行查询数据库,将查询结果更新到缓存

(高并发情况下,此时线程A还未完成数据库更新操作,线程B查询到的数据是旧数据,将旧数据更新到了缓存)
线程C查询缓存-----》取到线程B更新的旧的缓存数据,从而导致缓存数据和数据库数据不一致问题

        3、解决方案

解决方案一:先操作缓存再操作数据库:
解决原理:

使用延迟双删,数据库A在更新数据库后,再次删除缓存;

问题又来了:为啥要延迟(让线程A  sleep个500ms(具体时间根据项目定))?

因为:不延迟有可能线程B已经到查数据库那步,但已经查到旧数据,此时线程A第二次删除了,线程B又查询到了旧数据再更新缓存,则会导致不一致;
缺陷:

a、延迟双删能保证数据最终一致性,在线程B进行查询的时候还是会有一次查到旧数据

b、业务层进行线程休眠会影响高并发系统整体性能;

解决方案二:

异步延迟双删:在延迟双删的基础上,引入mq进行异步删除,不需要进行休眠,但引入MQ会增加系统复杂度;

解决方案三:
解决异步延迟删除:引入阿里的canal
canal原理:启一个进程,监听mysql的binlog日志文件,将有数据更新的数据进行写入mq去执行延迟删除

以上三个方案仅能保证数据最终一致性,始终会存在至少一次查询到旧数据;

想要保证数据强一致性,可以加锁,但是加锁,会影响整体性能,得不偿失;

方案二(推荐方案):
先更新数据库,再删除缓存

(能保证数据库最终一致性,但也会存在一次查询到旧数据)
存在问题:更新数据库成功,删除缓存失败怎么解决?使用mq发送到消息队列,进行重试,一样可以使用阿里的canal框架;

二、缓存在高并发情况下存在的问题及解决方案
4、缓存穿透:
a、当黑客用一个不存在的key一直请求,请求直接穿到mysql数据库,从而导致系统资源占用导致系统不可用;

b、解决方案:使用布隆过滤器,快速过滤黑名单信息


5、缓存击穿:
a、某些key在一个时间点全部失效,导致请求全部到mysql层,mysql系统不可用,从而引起整个系统奔溃;(比如秒杀结束,某些秒杀商品)

b、解决方案:

加时间节点判断秒杀是否结束

给秒杀商品设置随机过期时间,而非固定过期时间,使得所有的key不在同一时间过期

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值