缓存穿透、击穿、雪崩的解决方法

一、缓存穿透指的是查询一个不存在的数据,由于缓存中没有对应的值,每次请求都要查询数据库,容易导致数据库压力过大。

解决方法:

  1. 使用布隆过滤器等手段可以在请求到达后台处理之前就过滤掉这些不存在的请求,避免了对数据库的访问。例如在给定的场景中,布隆过滤器用于检查数据是否存在,如果不存在则直接返回错误信息,而不需要在访问数据库。
  2. 将查询为空的 key 也缓存起来,但是设置一个较短的过期时间,防止缓存层被大量无效请求填满。
  3. 在应用层对请求参数进行校验,过滤掉无效的请求。

二、缓存击穿指的是一个热点数据失效后,大量并发请求同时访问数据库,导致数据库压力过大。

解决方法:

  1. 在缓存失效时,使用互斥锁或分布式锁来保护后端系统的访问,只允许一个线程去查询数据库,其他线程等待查询结果,避免了大量并发请求穿透到后端系统。
  2. 可以使用热点数据预加载或预热缓存,在即将过期的缓存数据失效前提前重新加载,避免热点数据因缓存失效而引发击穿问题。

例如,redis在高并发下,为了避免请求直接打到数据库,可以使用双重检查锁的方式进行数据库查询。不设置双重检查的话,那在第一个获取锁的线程同步数据库到Redis期间堆积的所有线程都会在获取锁后查询数据库并设置缓存。具体步骤如下:

  1. 先查 redis 中是否有数据
  2. 如果 redis 中没有数据,使用 synchronized 进行加锁
  3. 再次查询 redis 中是否有数据
  4. 如果第3步查询还是没有数据,此时再查数据库
  5. 查询到数据库中的数据后,将数据写入到redis中。

代码示例:

java 复制代码
    public String getDataFromDatabase(String key) {
        // 先查 Redis 中是否有数据
        String data = jedis.get(key);

        // 第一重检查,如果 Redis 中有数据,直接返回
        if (data != null) {
            return data;
        }
        // 使用双重检查锁的方式避免多线程同时查询数据库
        if (lock.tryLock()) {
            try {
                // 第二重检查,再次查询 Redis 中是否有数据
                data = jedis.get(key);
                if (data != null) {
                    return data;
                }
                // 模拟从数据库中查询数据
                data = fetchDataFromDatabase(key);
                // 将查询到的数据写入 Redis 中
                jedis.set(key, data);
            } finally {
                // 释放锁
                lock.unlock();
            }
        }
        return data;
    }

三、缓存雪崩指的是缓存中的大量数据同时失效,导致大量请求直接访问数据库,造成数据库瞬时压力过大。

解决方法:

  1. 给缓存数据设置随机的过期时间,避免大量缓存同时失效。
  2. 使用多级缓存架构,如主从复制、分布式缓存等,减少单点故障风险。
  3. 引入熔断机制或限流策略,当缓存层面发生雪崩时,限制对后端系统的请求,保护后端系统免受过载。
相关推荐
uhakadotcom28 分钟前
什么是Mass Assignment(批量赋值)风险
后端·面试·github
正经教主35 分钟前
【docker基础】Redis的docker部署
redis·docker·容器
努力成为AK大王35 分钟前
计算机底层核心原理:CPU、总线、缓存与内存深度解析
缓存·内存·cpu
闪电悠米1 小时前
黑马点评-Redis 消息队列-04_stream_seckill_order
数据库·redis·分布式·缓存·oracle·junit·lua
成为你的宁宁1 小时前
【基于 Prometheus Operator 实现 K8s 环境下 Redis Cluster 集群监控部署】
redis·kubernetes·prometheus
公考指南针1 小时前
公务员面试怎么准备?2026 结构化面试流程、答题训练和备考工具测评
经验分享·学习·面试
bmjIjFNC81 小时前
Redis分布式锁进第九十一篇
数据库·redis·分布式
维尔康1 小时前
【无标题】
redis
通信侠2 小时前
android相机热启动缓存帧解决方案(任务快照)
android·缓存·blur·tasksnapshot·mtkcam
AOwhisky2 小时前
Redis 学习笔记(第二期):核心数据类型与消息队列实战
运维·数据库·redis·笔记·学习·云计算