Redis面试二“缓存击穿是什么”

2023-09-21 20:30:05

条件

缓存击穿是应为Redis某个缓存数据设置了过期时间,而刚好有大并发数据请求这个数据,导致DB有大量请求,引发DB崩溃。

第一种方法就是设置互称锁

当缓存失效时不立即删除缓存而是用setnx设置一个互斥锁,当操作完成后在load db,并回设缓存,否则重试get缓存方法,这样就减少了直接大量访问DB的请求。

实现

@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRoleDO> implements SysRoleService {

    @Resource
    private RedissonClient redissonClient;

    @Override
    public List<SysRoleDO> test() throws Exception {
        Object roles = redissonClient.getBucket("role").get();
        // 先查询缓存,缓存中有则直接返回
        if (Objects.nonNull(roles)) {
            return JSON.parseArray(roles.toString(), SysRoleDO.class);
        }
        RLock lock = redissonClient.getLock("role-lock");
        boolean isLock = lock.tryLock();
        if (isLock) {
            // 获取到锁查询数据库,并将查询结果放入缓存
            try {
                Object roleList = redissonClient.getBucket("role").get();
                // 双重检查锁,当多个线程同时判断到缓存中取不到值,上一个获取到锁的线程已经将数据放入缓存,下一个线程直接取缓存
                if (Objects.nonNull(roleList)) {
                    return JSON.parseArray(roleList.toString(), SysRoleDO.class);
                }
                // 查询数据库
                List<SysRoleDO> list = this.list();
                // 将数据放入缓存
                redissonClient.getBucket("role").set(list, 60L, TimeUnit.SECONDS);
                return list;
            } finally {
                lock.unlock();
            }
        }
        int retryTimes = 3;
        Object roleList = null;
        // 当缓存中取不到值时sleep300毫秒,最多循环3次
        while (Objects.isNull(roleList) && retryTimes > 0) {
            // 休眠300ms后递归
            TimeUnit.MILLISECONDS.sleep(300L);
            roleList = redissonClient.getBucket("role").get();
            retryTimes--;
        }
        // 循环等待后缓存中取到值直接返回,仍然取不到值则抛异常
        if (Objects.nonNull(roleList)) {
            return JSON.parseArray(roleList.toString(), SysRoleDO.class);
        }
        throw new RuntimeException("查询异常");
    }
}

第二种解决缓存击穿的实现就是设置key逻辑过期时间

1.在设置key的时候过期时间字段并一块存入缓存,不给当前key设置过期时间。

2.当查询的时候在redis中判断是否过期,条件就是字段设置时间与当前时间对比。

3.如果过期就开通另一个线程进行数据同步,当前线程正常返回数据,但数据就不是最新的时老的数据不能保证强一致。

实现

//逻辑过期
    public Shop queryWithLogicalExpire(Long id) {
        String key = CACHE_SHOP_KEY + id;
        //1.从redis查询商铺缓存
        String shopJson = stringRedisTemplate.opsForValue().get(key);
        //2.判断是否存在
        if (StrUtil.isBlank(shopJson)) {
            //3.未命中
            return null;
        }
        //4.命中,需要先把json反序列化为对象
        RedisData redisData = JSONUtil.toBean(shopJson, RedisData.class);
        Shop shop = (Shop) redisData.getData();
        LocalDateTime expireTime = redisData.getExpireTime();
        //5.判断是否过期
        if (expireTime.isAfter(LocalDateTime.now())) {
            //5.1还未过期
            return shop;
        }
        //5.2已经过期,需要缓存重建
        //6.缓存重建
        //6.1获取互斥锁
        String lockKey = LOCK_SHOP_KEY + id;
        boolean isLock = tryLock(lockKey);
        //6.2判断是否获取锁成功
        if (isLock) {
            // 6.3成功,开启独立线程,实现缓存重建
            CACHE_REBUILD_EXECUTOR.submit(() -> {
                try {
                    //重建缓存
                    this.saveShop2Redis(id, 20L);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    //释放锁
                    unlock(lockKey);
                }
            });
        }
        //6.4返回过期的店铺信息
        //7.返回
        return shop;
    }

总结

如果要求数据的强一致测使用分布式锁,如果要求高可用就使用逻辑过期就可以了。

更多推荐

机器视觉检测在流水线上的技术应用

机器视觉在流水线上的应用机器视觉系统的主要功能可以简单概括为:定位、识别、测量、缺陷检测等。相对于人工或传统机械方式而言,机器视觉系统具有速度快、精度高、准确性高等一系列优点。随着工业现代化发展,机器视觉已经广泛应用于各大领域。为企业及用户提供更优的产品品质及完美解决方案。流水线视觉检测是机器视觉应用最多的场合,流水线

视觉检测系统可以检测太阳能电池片哪些方面的缺陷?

近年来,随着全球工业化进程的不断加快,能源与环境危机成为一个亟待解决的问题。为此,太阳能作为一种清洁可再生的能源,现已被广泛应用于各领域。太阳能电池片作为太阳能转换为电能的核心载体,其质量的好坏决定着电能的转换效率。在从硅片到太阳能电池片的生产过程中会产生污点、破损等各种缺陷,需要进行多重检测工序。手动检测效率低下,容

unordered_set和unordered_map的封装

目录一、前言二、容器的使用1、unordered_map2、unordered_set​编辑三、哈希表的改造1、结点2、哈希表的迭代器*构造函数*重载**重载->*重载++*重载!=和==3、哈希表的析构4、unordered_map的[]实现5、修改后的哈希表四、unordered_set的实现五、unordered

NSS [NISACTF 2022]is secret

NSS[NISACTF2022]issecret原题是[CISCN2019_华东南赛区]Double_Secret开题蒙蔽。猜测是/secret路由,猜对了。GET提交参数?secret=1,这里应该是一个注入点。看了一下network,后端语言是python2,不确定是哪种漏洞,所有想到的都测一遍,最后在测SSTI时

【2023年11月第四版教材】第14章《沟通管理》(第二部分)

第14章《沟通管理》(第二部分)4规划沟通管理4.1规划沟通管理4.2沟通技术4.3沟通模型4.4沟通方法★★★(22下案例)4.5人际关系与团队技能4.6沟通管理计划★★★(18下44)(13上论文)(22下案例)5管理沟通5.1管理沟通5.2沟通技能5.3人际关系与团队技能6监督沟通6.1监督沟通★★★6.2人际关

Tomcat架构设计及组件详解

继Tomcat配置详解(Tomcat配置server.xml详解)Tomcat配置详解(Tomcat配置server.xml详解)_tomcatxml配置https://blog.csdn.net/imwucx/article/details/132166738文章之后,深入的学习tomcat相关知识,对Tomcat的

自动驾驶中的决策规划

参考:【干货篇】轻舟智航:自动驾驶中的决策规划技术(附视频回放+PPT下载)-AIQ如图所示,各模块介绍定位模块主要负责解答的问题是“车现在在哪里”,是在道路上还是在路口,是在高架桥上还是在停车场里。感知模块则负责解答“车周围有什么”这个问题。预测模块,预测模块主要解答“周围的车现在想干什么”,比如前面的车要cutin

全流程HEC-RAS 1D/2D水动力与水环境模拟丨恒定流模型(1D/2D)、一维非恒定流、二维非恒定流模型、HEC-RAS水质模型

目录​专题一​水动力模型基础专题二恒定流模型(1D/2D)专题三一维非恒定流专题四二维非恒定流模型(一)专题五二维非恒定流模型(二)专题六HEC-RAS的水质模型专题七高级主题更多应用水动力与水环境模型的数值模拟是实现水资源规划、环境影响分析、防洪规划以及未来气候变化下预测和分析的主要手段。然而,一方面水动力和水环境模

3D点云目标检测:Centerformer训练waymo数据集

一、环境准备项目地址:centerformer1.0、基础环境python==3.8.0torch==1.9.1+cu111waymo-open-dataset-tf-2-6-0==1.4.9spconv==1.2.1其余按照requirement.txt里安装就行pipinstall-ihttps://pypi.tu

用微服务平台框架,实现高效的流程化办公!

想要实现流程化办公,可以用什么样的软件平台实现?随着市场竞争越来越激烈,很多企业会采用低代码技术平台实现高效管理企业的内部资源,从而减少很多繁琐工作和时间,实现提质增效的目的。流辰信息助力大家采用微服务平台框架低代码技术平台打破信息孤岛,创造高效办公。低代码的便捷性和灵活性就不言而喻了,它在企业的发展过程中扮演了非常重

K8S-存储卷,pv,pvc

pv,pvc一、emptyDir存储卷1.概述2.示例二、hostPath存储卷1.概述三、nfs共享存储卷1.在stor01节点上安装nfs,并配置nfs服务2.master节点操作3.在nfs服务器上创建index.html4.master节点操作四、PVC和PV1.概述2.PV和PVC之间的相互作用遵循的生命周期

热文推荐