首页 > 数据库 >Redis的缓存穿透、缓存雪崩、缓存击穿问题及解决方案

Redis的缓存穿透、缓存雪崩、缓存击穿问题及解决方案

时间:2023-09-10 22:57:52浏览次数:34  
标签:缓存 过期 redis 数据库 Redis 线程 雪崩 数据

Redis的缓存穿透、缓存雪崩、缓存击穿问题及解决方案

缓存穿透问题及解决思路

缓存穿透 :缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。因为我们查数据通常是现在redis缓存查数据,如果redis没有这个数据,就会去数据库查。如果张三想要搞垮数据库,就会发送大量请求来查询redis和数据库都没有的数据库,在这样高并发请求下,数据库就会被搞崩了。所以redis在某个方面相当于保护了数据库的服务器。

要解决缓存穿透,有两种方法:1.在redis中缓存空对象;优点:实现简单,维护方便;缺点:消耗redis内存。2.布隆过滤,优点:内存占用少,没有多于的key;缺点:可能会出现误判,因为布隆过滤器原理是用哈希思想来判断这个值在数据库中存不存在,但是有哈希思想就可能会存在哈希冲突。

image-20230910222317604

缓存雪崩问题及解决思路

缓存雪崩顾名思义就是Redis服务器宕机了,或者是在同一时段大量的缓存key同时失效;这两个都会让大量请求到达数据库,从而给数据库带来巨大压力。

解决方案:

  • 给不同的key的TTL(过期时间)设置随机值,只要过期时间不一样,那么就不会同时过期。
  • 利用Redis集群提高服务的可用性,既然害怕服务器宕机,那就设置一个redis集群(3主3从或者1主多从或者1主一从),这样一个服务器宕机了,其他的可以代替。
  • 给缓存业务添加降级限流策略
  • 给业务添加多级缓存

image-20230910223018379

缓存击穿问题及解决思路

缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。常见场景如商品秒杀。

常见的解决方案有两种:

  • 互斥锁
  • 逻辑过期

解决方案一、使用锁来解决:

因为锁能实现互斥性。假设线程过来,只能一个人一个人的来访问数据库,从而避免对于数据库访问压力过大,但这也会影响查询的性能,因为此时会让查询的性能从并行变成了串行,我们可以采用tryLock方法 + double check来解决这样的问题。

假设现在线程1过来访问,他查询缓存没有命中,但是此时他获得到了锁的资源,那么线程1就会一个人去执行逻辑,假设现在线程2过来,线程2在执行过程中,并没有获得到锁,那么线程2就可以进行到休眠,直到线程1把锁释放后,线程2获得到锁,然后再来执行逻辑,此时就能够从缓存中拿到数据了。

image-20230910223349554

解决方案二、逻辑过期方案

方案分析:我们之所以会出现这个缓存击穿问题,主要原因是在于我们对key设置了过期时间,假设我们不设置过期时间,其实就不会有缓存击穿的问题,但是不设置过期时间,这样数据不就一直占用我们内存了吗,我们可以采用逻辑过期方案。

我们把过期时间设置在 redis的value中,注意:这个过期时间并不会直接作用于redis,而是我们后续通过逻辑去处理。假设线程1去查询缓存,然后从value中判断出来当前的数据已经过期了,此时线程1去获得互斥锁,那么其他线程会进行阻塞,获得了锁的线程他会开启一个 线程去进行 以前的重构数据的逻辑,直到新开的线程完成这个逻辑后,才释放锁, 而线程1直接进行返回,假设现在线程3过来访问,由于线程线程2持有着锁,所以线程3无法获得锁,线程3也直接返回数据,只有等到新开的线程2把重建数据构建完后,其他线程才能走返回正确的数据。

这种方案巧妙在于,异步的构建缓存,缺点在于在构建完缓存之前,返回的都是脏数据。

1653328663897

进行对比

互斥锁方案:由于保证了互斥性,所以数据一致,且实现简单,因为仅仅只需要加一把锁而已,也没其他的事情需要操心,所以没有额外的内存消耗,缺点在于有锁就有死锁问题的发生,且只能串行执行性能肯定受到影响

逻辑过期方案: 线程读取过程中不需要等待,性能好,有一个额外的线程持有锁去进行重构数据,但是在重构数据完成前,其他的线程只能返回之前的数据,且实现起来麻烦

标签:缓存,过期,redis,数据库,Redis,线程,雪崩,数据
From: https://www.cnblogs.com/ahui-blog/p/17692202.html

相关文章

  • 七、Nginx缓存机制
    对于性能优化而言,缓存是一种能够大幅度提升性能的方案,因此几乎可以在各处都能看见缓存,如客户端缓存、代理缓存、服务器缓存等等,Nginx的缓存则属于代理缓存的一种。对于整个系统而言,加入缓存带来的优势额外明显:减少了再次向后端或文件服务器请求资源的带宽消耗。降低了下游服务器的......
  • 监听canal实现缓存同步
           ......
  • Linux下安装Redis的详细安装步骤
    一.Redis安装1.下载linux压缩包【redis-5.0.5.tar.gz】2.通过FlashFXP把压缩包传送到服务器3.解压缩tar-zxvfredis-5.0.5.tar.gz4.进入redis-5.0.5可以看到redis的配置文件redis.conf5.基本的环境安装使用gcc-v命令查看gcc版本已经是4.8.5了,于是就没有再次安装,直接......
  • nginx本地缓存
           ......
  • 查询Redis
            ......
  • python学习笔记-redis缓存数据库
    一、缓存数据库介绍NoSQL(notonlysql)redis是业界主流的Key-valuenosql数据库之一,和memcached类似redis优点:速度快,每秒可执行大约110000设置操作,81000个/每秒的读取操作支持丰富的数据类型,列表,结合,可排序集合,哈希等操作是原子的二、redis操作安装redisubuntu安装$......
  • 多级缓存-Redis缓存预热
            ......
  • Redis基础
    1.什么是RedisRedis是一个基于C语言开发的内存数据库,读写速度非常快,广泛应用于缓存方向。并且,Redis存储的是KV键值对数据。Redis内置了多种数据类型实现(比如String、Hash、SortedSet、Bitmap)。并且,Redis还支持事务、持久化、Lua脚本、多种开箱即用的集群方案(RedisSe......
  • Redis7 安装配置
    一、概述由于企业里面做Redis开发,99%的都是Linux版的运用和安装,几乎不会涉及到Windows版二、依赖Linux安装Redis必须先具备gcc编译环境gcc-v安装redis之前需要具备c++库环境yuminstall-ygcc-c++三、版本选择四、安装步骤1、下载命令:wgethttps://download.redis.io/release......
  • redis
    博客地址:https://www.cnblogs.com/zylyehuo/五大数据类型参考链接:redis学习string,字符串类型hash,哈希类型,如同python的dictset,无序集合zset,有序集合list,双向队列,向左插入数据,向右插入数据,向左、右,提取数据redis安全启动与配置文件,运维相关操作redis如何在linux安......