千家信息网

JAVA缓存击穿、缓存穿透、缓存雪崩的区别有哪些

发表于:2025-11-17 作者:千家信息网编辑
千家信息网最后更新 2025年11月17日,这篇文章主要介绍"JAVA缓存击穿、缓存穿透、缓存雪崩的区别有哪些",在日常操作中,相信很多人在JAVA缓存击穿、缓存穿透、缓存雪崩的区别有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作
千家信息网最后更新 2025年11月17日JAVA缓存击穿、缓存穿透、缓存雪崩的区别有哪些

这篇文章主要介绍"JAVA缓存击穿、缓存穿透、缓存雪崩的区别有哪些",在日常操作中,相信很多人在JAVA缓存击穿、缓存穿透、缓存雪崩的区别有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"JAVA缓存击穿、缓存穿透、缓存雪崩的区别有哪些"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

调用链路

一个请求Request过来,服务器首先和缓存中间件建立连接,传输对应key到缓存中间件中获取相对应的数据,服务器拿到返回的结果后,判断返回的结果是否有数据,如果有数据,则返回从缓存中拿到的结果。如果缓存中间件中没有数据,则建立数据库连接,访问数据库服务器,按照相应逻辑拿到返回结果,判断结果中是否有数据,如果有则返回对应数据,如果没有则按照业务场景要求,返回对应结果(一般为null或者new一个空对象)。

缓存击穿

含义:

什么是缓存击穿?通俗的讲指的是缓存中没有数据,但数据库中有数据的场景。那为什么缓存中会没有数据呢?一般是由于设置了缓存时间导致缓存过期,所以没有数据。那缓存找不到数据去数据库查询就好了呀,为啥又叫击穿?是因为要查询这个key对应的数据是一个热点数据,并发访问的量大,同时去查询数据库,导致数据库压力骤增,严重会打崩数据库。

解决方案:

1、如果是不改变的数据,如一些常量值,则可以设置对应热点key永不过期。

2、加上互斥锁,防止同一台服务器同一时间有多个连接访问数据库。

// 伪代码public class Main {    // 双重检测锁    public static String getHotData(String key) {        // 先从缓存中间件获取对应热点key数据        String response = redis.get(key);        // 缓存没有数据        if(Objects.isNull(response)) {            // 保证一台服务器同一时间只有一个线程访问            synchronized (Main.class) {                // 假设A线程访问进synchronized里,线程B, C阻塞在synchronsized外面                // 线程A退出synchronized后,线程B和C应该从redis中拿而不是再访问数据库                response = redis.get(key);                // 访问数据库 拿到数据后 写进redis中                if(Objects.isNull(response)) {                    response = loadDataFromMySQL(key);                    redis.set(key, response);                }            }        }        return response;    }}

3、加上分布式锁,全局保证只有一个线程访问数据库。

// 伪代码public class Main {    // 分布式唯一key    public static String getHotData(String key, int tryTime) throws InterruptedException {        if(tryTime >= 4) {            return "";        }        // 先从缓存中间件获取对应热点key数据        String response = redis.get(key);        // 缓存没有数据        if(Objects.isNull(response)) {            // 保证整个服务集群同一时间只有一个线程访问            if (redis.tryLock()) {                try {                    // 访问数据库 拿到数据后 写进redis中                    if(Objects.isNull(response)) {                        response = loadDataFromMySQL(key);                        redis.set(key, response);                    }                } finally {                    redis.unlock();                }            } else {                TimeUnit.MILLISECONDS.sleep(100);                getHotData(key, tryTime + 1);            }        }        return response;    }}

缓存穿透

含义:

缓存穿透指的是缓存中间件和数据库都没有对应的数据,但是不断接收到请求获取该key的数据,导致数据库压力过大,甚至崩溃。

解决方案:

1、访问数据库也拿不到数据后,可以按照具体业务要求,在缓存层加上一个该key的值,设置一个过期时间,比如10s或者1min等。那为什么不设不过期呢?第一个是说因为该key可能有对应的业务含义,有可能只是该时间点还没有数据,所以不能设置不过期;第二个是说如果真的是恶意访问,那么可能过一段时间就没有类似请求,那么我们没有必要一直把该数据留在缓存里。

2、增加校验,如果是不符合预期的请求可以直接过滤,比如说缓存中存放了用户信息,对应的缓存key是和id有关系,那么如果你的id都是大于等于0的,对于小于0的id可以直接做过滤。

@Controllerpublic class Controller {        @RequestMapping(value="/test")        public String printHello(Integer id) {        if(Objects.isNull(id) || id < 0) {            return null;        }                // 处理对应逻辑        }}

缓存雪崩

含义:

缓存雪崩指的是在同一个时间点,缓存中的大批量数据过期,并且还都是热点数据,导致同一时间并发压力都打到了数据库中,导致数据库压力骤增,甚至宕机。有的人就会问了,这和缓存击穿不是一个意思吗?缓存击穿指的是并发查询某条热点key数据,缓存雪崩指的是大批量。出现场景之一是在某些核心页面,该页面的内容都放入了缓存,并且都设置了同样的缓存时间。

解决方案:

1、最简单的就是设置热点数据不过期,但要结合对应业务场景来看。

2、在给每个热点key设置过期时间时,加上一个随机值,使得热点数据离散开来,不会同一时间大批量过期。

3、使用缓存击穿场景讲到的互斥锁、分布式锁。

到此,关于"JAVA缓存击穿、缓存穿透、缓存雪崩的区别有哪些"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

数据 缓存 数据库 时间 热点 雪崩 线程 穿透 中间件 结果 服务 场景 服务器 业务 压力 含义 学习 查询 分布式 只有 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 r星服务器连接失败无法建立连接 山东交友软件开发哪家好 公安网络安全技术视力 重庆双桥区苹果软件开发公司 最全小说软件开发 北京在线网络技术服务选择 系统无法提交数据库 慈溪安卓软件开发工具 数据库中存在众多的数 修改建造师数据库的申请表 网络安全工作报告 教育局 银行数据中心网络安全好吗 数据库安全演练 服务器密码管理本 正在下载游戏重要数据库 服务器数据库怎么看 医保网络安全分析 电脑家庭还是工作网络安全 关于数据库DB 菏泽供热站自动化控制软件开发 经营范围软件开发服务 珠海模具公司erp软件开发 深圳美达软件开发 海康刻录机怎么设置服务器存储 北京小型软件开发销售电话 张家港正规网络技术采购 学习手机软件开发怎么样 剑网3 捏脸二少数据库 电信行业是网络安全防护 用登录名怎么创建新的数据库
0