Redis的缓存穿透,缓存击穿,雪崩问题及解决

1.为什么使用redis

1.1 问题背景

在实际应用场景中每一次进行查询服务的时候都需要访问数据,而数据存在于数据库中,我们就需要每次都将访问请求打到数据库中,这样大大加重了数据库负担,当并发量过大时还会导致系统崩溃宕机。

1.2 解决方式

首先,我们的方案选择redis,它是一个非关系型数据库,是以key-value形式存储数据的存储系统。第二,redis是存在于内存中的,这里就是牺牲空间来换取查询时间的一个思想,并且存放于内存中的数据读写速度都是很快的,还实现了数据持久化。总之,它能解决数据库负担的原因就是因为它用作缓存,1.可以减轻数据库压力 2.可以提高查询效率。

当数据库数据进行更新添加时,会刷新redis中存放的数据,作为当前数据的缓存,在进行访问请求的时候,就会先访问redis,如果redis中没有才会去访问数据库。

但是,这样也引发了一系列问题,缓存穿透,缓存击穿,雪崩。

2.什么是缓存的穿透,击穿,雪崩

2.1 什么是缓存穿透

缓存穿透:当用户要访问的数据在缓存中没有时,就会去访问数据库,并且查询完数据库后
发现连数据库中也访问不到数据,这就使后面的请求都会访问到数据库,这就是缓存穿透。

2.2 什么是缓存击穿

缓存击穿:当redis存储的某一数据过期后,有大量的请求需要获取这个过期的数据,那么
就会去直接访问数据库,这样使数据库压力剧增,这就是缓存击穿。

2.3 什么是雪崩

缓存雪崩:简单说就是缓存击穿的复数形式,当多个缓存同时过期或者redis出现故障时,
有大量请求要来访问这些数据,redis无法处理,从而把访问压力全部打到数据库中,可能
造成数据库崩溃导致系统崩溃的连锁反应,这就是缓存雪崩。

3.解决方案

3.1 缓存穿透

解决方式:1.非法请求限制 2.缓存空值或者默认值 3.布隆过滤器(吹底层即可)
这里我们实现了第二种方式当缓存中没有数据时,我们接下来要查数据库,在查数据库后,
若有数据直接设置数据即可,如果没有数据,也把查询出来的空值或者默认值也设置进去,
这样就实现了而后来的请求查询当前数据是有值的但是是个空值,这就解决了缓存穿透问题

3.2 缓存击穿

解决方式:使用互斥锁,先拦截所有请求,实现仅有第一个请求访问数据库资源,若缓存有
则直接返回,如果没有那么将查询数据库,并把数据设置到缓存中,而后的所有请求都不用
访问数据库了。

3.3 缓存雪崩

解决方式:1.均匀设置过期时间2.互斥锁 2.双key策略
1.这种方式可以使用最高响应比算法进行实现,设置一个记录位,记录访问次数,赋予权重
对每一次访问后过期时间都进行修改更新。还可以使用最佳平均等待时间算法进行实现。
2.互斥锁,这种方式和缓存击穿所用思想相同。
3.双key策略,设置一个主key一个备key,主key有过期时间,备key不会过期,当主备都
没有时才会访问数据库并设置双key缓存,当主key没有备key有时直接返回备key数据。

4. 部分面试题

1 你的项目中那个地方使用到了缓存? 为什么要用缓存?
车辆类型加载的时候使用到了缓存技术,使用缓存的目的是为了缓解数据库压力
让每一次发送的查询请求先在缓存中查找,也大大提高了查询效率,节省CPU调度资源

2 为什么要用redis缓存不用mybatis二级缓存?
mybatis二级缓存只适用于在当前项目中进行缓存,而我们的项目需要进行分布式缓存
,意味着当两个应用服务查询数据库时,有可能其中一个获取的本地缓存数据是没有进行
更新的,就会出现数据匹配不上问题,使用redis缓存就可以解决缓存不同步问题,数据库数据
会同步一份到redis中,每次查询直接访问redis获取数据即可。

3 用了redis缓存后有什么好处?
降低数据库压力,访问请求不用全部发送到数据库,直接在内存中获取
以空间换时间,效率高。

4 你是怎么实现缓存的?怎么做的
在项目中先配置redis,调用redisTemplate设置键值,过期时间。
用户请求车辆类型数据时,先在redis缓存中获取,如果有直接返回,如果没有则从数据库中
获取并设置redis缓存。当然这里会涉及到缓存穿透、击穿、雪崩问题。

5 项目中为什么不使用springcache
使用springcache能够快速的进行缓存实现,但是在缓存中存在问题如缓存穿透、击穿、雪崩
springcache并没有进行处理,所以需要我们自己实现缓存能有针对性的解决问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于 Redis 缓存的穿透、击穿和雪崩问题,可以采取以下解决方案: 1. 缓存穿透:当请求的数据在缓存中不存在时,会直接访问数据库,如果有恶意攻击者大量请求不存在的数据,会给数据库造成很大压力。解决方案可以是在查询前进行参数校验,比如对请求的参数进行合法性检查,或者使用布隆过滤器等技术来快速判断请求的数据是否存在。 2. 缓存击穿:当某个热点数据过期或被删除时,大量请求同时涌入,导致请求直接访问数据库。为了解决这个问题,可以使用互斥锁(Mutex)或者分布式锁来避免多个请求同时访问数据库。在获取锁之前,首先尝试从缓存获取数据,如果缓存中存在,则直接返回;如果不存在,则获取锁,并从数据库中获取数据并放入缓存,最后释放锁。 3. 缓存雪崩:当缓存中的大量数据同时过期时,会导致大量请求直接访问数据库,给数据库带来巨大压力。为了解决这个问题,可以采取以下措施: - 设置合理的缓存过期时间,使得不同数据的过期时间错开,避免同时失效。 - 使用热点数据预加载,提前将热点数据加载到缓存中,避免同时失效。 - 使用多级缓存架构,将缓存分为多个层级,不同层级的缓存设置不同的过期时间,从而降低缓存失效的风险。 - 引入限流和熔断机制,对请求进行限制,避免大量请求同时访问数据库。 通过以上措施,可以有效地解决 Redis 缓存穿透、击穿和雪崩问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值