解决Redis中缓存穿透、击穿与雪崩问题:Java

解决 Redis 缓存穿透 / 击穿 / 雪崩以及数据一致性的方案 无论是在开发过程中还是在准备跑路的面试过程中,有关redis相关的,难免会涉及到四个特殊场景:缓存穿透、缓存雪崩、缓存击穿以及数据一致性。如果在开发中不注意这些场景的话,在高并发场景下有可能会导致系统崩溃,数据错乱等情况。现在,结合实际的业务场景来复现并解决这些问题。 阅读详情

Redis缓存穿透,通常是有人大量访问未知的URL,导致后端穿透Redis,直接访问数据库,这里采用在Redis中注入空key来解决;

Redis缓存击穿,通常为Redis热点key失效问题,导致大量请求同时访问这个key,转而访问数据库,这里采用Redis读延期以及DCl做数据库读取解决;

Redis缓存雪崩,通常为Redis大量key同时失效导致,解决方案,生成随机过期时间,防止同时失效。

//本地缓存map
    private static Map<String,GoodsVo> goodsVoMap=new HashMap<>();
//这个map如果商品过多,有可能超出内存OOM,其次还有分布式缓存一致性问题,这里是本地Map
//也许能通过ConcurrentHashMap实现LRU来解决
    @RequestMapping(value = "/detail/{goodsId}")
    @ResponseBody
    public RespBean toDetail(HttpServletRequest request, HttpServletResponse response, Model model, User user, @PathVariable Long goodsId) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        GoodsVo goods = getGoodsFromCache(goodsId);
        if (goods == null) {
            //DCL
            boolean lock = valueOperations.setIfAbsent("lock:goodsId:" + goodsId, goodsId, 1, TimeUnit.SECONDS);
            try {
                if (lock) {
                    goods = getGoodsFromCache(goodsId);
                    if (goods == null) {
                        goods = goodsService.findGoodsVoByGoodsId(goodsId);
                        //数据库包含数据
                        if (goods != null) {
                            valueOperations.set("goodsDetail:" + goodsId, JsonUtil.object2JsonStr(goods), genGoodsCacheTimeout(), TimeUnit.SECONDS);
                            goodsVoMap.put("goodsDetail:" + goodsId,goods);
                        } else {
                            //数据库为空,放入空值
                            valueOperations.set("goodsDetail:" + goodsId, EMPTY_CACHE, genEmptyCacheTimeout(), TimeUnit.SECONDS);
                        }
                    }
                }
            } finally {
                redisTemplate.delete("lock:goodsId:" + goodsId);
            }
        }
        Date startDate = goods.getStartDate();
        Date endDate = goods.getEndDate();
        Date nowDate = new Date();
        //秒杀状态
        int secKillStatus = 0;
        //剩余开始时间
        int remainSeconds = 0;
        if (nowDate.before(startDate)) {
            remainSeconds = (int) ((startDate.getTime() - nowDate.getTime()) / 1000);
        } else if (nowDate.after(endDate)) {
            secKillStatus = 2;
            remainSeconds = -1;
        // 秒杀中
        } else {
            secKillStatus = 1;
            remainSeconds = 0;
        }
        DetailVo detailVo = new DetailVo();
        detailVo.setGoodsVo(goods);
        detailVo.setUser(user);
        detailVo.setRemainSeconds(remainSeconds);
        detailVo.setSecKillStatus(secKillStatus);
        return RespBean.success(detailVo);
    }

    private GoodsVo getGoodsFromCache(Long goodsId) {
        GoodsVo goods = null;
        //jvm进程级别缓存,实际就是内存
        //单机内存比redis更高,可以达到百万级并发
        goods=goodsVoMap.get("goodsDetail:" + goodsId);
        if(goods!=null){
            return goods;
        }
        ValueOperations valueOperations = redisTemplate.opsForValue();
        String goodsDetail = (String) valueOperations.get("goodsDetail:" + goodsId);
        if (!StringUtils.isEmpty(goodsDetail)) {
            if (EMPTY_CACHE.equals(goodsDetail)) {
                //空值返回错误
                redisTemplate.expire("goodsDetail:" + goodsId, genEmptyCacheTimeout(), TimeUnit.SECONDS);
                return new GoodsVo();
            }
            goods = JsonUtil.jsonStr2Object(goodsDetail, GoodsVo.class);
            //读延期
            redisTemplate.expire("goodsDetail:" + goodsId, genGoodsCacheTimeout(), TimeUnit.SECONDS);
        }
        return goods;
    }

    private Integer genGoodsCacheTimeout() {
        return 60 * 60 * 24 + new Random().nextInt(5) * 60 * 60;
    }

    private Integer genEmptyCacheTimeout() {
        return 60 + new Random().nextInt(30);
    }

Redis缓存击穿、缓存穿透和缓存雪崩 处理方法 阅读详情

相关推荐

【RTOS】 Vxworks 653 第一章 —— 初识 vx653 3.x

。。不是很重要,自己搜吧鲁棒分区是一种确保共享计算资源中独立运行功能实现​​时空隔离​​的机制,其目标是为集成模块中的混合临界性应用提供与联邦式部署(federated implementation)同等级别的功能隔离保障。具体表现为:​​多关键性共存​​:支持不同安全等级应用(如飞控系统A级与娱乐系统D级)在同一模块中协同运行。​​抗干扰能力​​:防止未授权或意外的时空干扰(如内存越界、时间窗口冲突),确保应用间互不影响。​​。

qq_38183694的博客 1280

redis缓存穿透,缓存击穿,缓存雪崩原因+解决方案

在我们日常的开发中,无不都是使用数据库来进行数据的存储,由于一般的系统任务中通常不会存在高并发的情况,所以这样看起来并没有什么问题,可是一旦涉及大数据量的需求,比如一些商品抢购的情景,或者是主页访问量瞬间较大的时候,单一使用数据库来保存数据的系统会因为面向磁盘,磁盘读/写速度比较慢的问题而存在严重的性能弊端,一瞬间成千上万的请求到来,需要系统在极短的时间内完成成千上万次的读/写操作,这个时候往往不是数据库能够承受的,极其容易造成数据库系统瘫痪,最终导致服务宕机的严重生产问题。

weixin_71690375的博客 428

数仓项目6.0(一)

数据同步工具种类繁多,大致可分为两类,一类是以DataX、Sqoop为代表的基于Select查询的离线、批量同步工具,另一类是以Maxwell、Canal为代表的基于数据库数据变更日志(例如MySQL的binlog,其会实时记录所有的insert、update以及delete操作)的实时流式同步工具。DataX的使用,用户只需根据数据的数据源和目的地选择相应的Reader和Writer,并将Reader和Writer的信息配置在一个json文件中,然后执行如下命令提交数据同步任务即可。

qq_58551342的博客 2849

Redis中的缓存穿透、雪崩、击穿的原因以及解决方案(详解)

redis中出现雪崩、击穿和穿透的原因以及如何进行解决

PeaK欢迎大家评论留言,一起交流Java技术 7万+

cutlass2.x源码解读之PitchLinearStripminedThreadMap

TensorCoord:使用layout::PitchLinearCoord作为张量坐标。Shape:使用模板参数Shape_作为tile的形状,kThreads:线程总数,定义为模板参数Threads。kElementsPerAccess:每次访问的元素数,定义为模板参数ElementsPerAccess。ThreadAccessShape:线程访问的形状,使用layout::PitchLinearShape定义。内部实现细节:ShapeVec。

jiangjkd的专栏 790

SBP依赖计算中的蝴蝶效应:一个Prefab修改如何触发全量重建?

本文深入探讨了Unity中SBP(Scriptable Build Pipeline)依赖计算的蝴蝶效应,解析了Prefab修改如何触发全量重建的机制。通过分析Asset与Object的层级关系、依赖计算的三种维度及CacheEntry系统,揭示了全量重建的根本原因,并提供了依赖可视化工具开发、优化策略与最佳实践,帮助开发者提升构建效率。

weixin_29015051的博客 445

《Redis缓存神器:解决缓存穿透、雪崩、击穿问题的完美方案》

这个时候,需要考虑一个问题:缓存被“击穿”的问题,这个和缓存雪崩的区别在于这里针对某一key缓存,前者则是很多key。单个简单的key存储的value很大,可以尝试将对象分拆成几个key-value,使用mget获取值,这样分拆的意义在于分拆单次操作的压力,将操作压力平摊到多次操作中,降低对redis的IO影响。缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。

成功最快的秘诀: 抱团取暖 。 1万+

C#实现低通和高通滤波算法

低通滤波器允许通过低于某个截止频率的信号成分,并且抑制高于该频率的成分。而高通滤波器则允许通过高于某个截止频率的信号成分,并抑制低于该频率的成分。巴特沃斯滤波器是一种对称的滤波器,具有平坦的幅度响应和最小的群延迟。低通和高通滤波是数字信号处理中常用的滤波技术,用于滤除或增强信号中的特定频率成分。在本篇文章中,我们将使用C#编程语言来实现低通和高通滤波算法。以上就是使用C#实现低通和高通滤波算法的示例代码。你可以根据自己的需求调整截止频率和采样率,将这些代码应用于你的项目中。是滤波器的截止频率,

XisVisual_Basic的博客 1275

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

缓存击穿指的是一个并发访问量比较大的key在某个时间过期,导致所有的请求直接打在DB上,那么程序在redis找不到数据,就会去数据库里查询,数据库处理大量的请求的同时导致压力瞬间增大,造成压力过大,甚至导致崩溃;缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。当某⼀时刻发⽣⼤规模的缓存失效的情况,例如缓存服务宕机、大量key在同一时间过期,这样的后果就是⼤量的请求进来直接打到DB上,可能导致整个系统的崩溃,称为雪崩。

一蓑烟雨任平生 2484

手把手教你学Simulink——基于电机驱动系统的场景实例:永磁同步电机(PMSM)在电动汽车中的矢量控制仿真

随着全球对环境保护的关注增加,电动汽车(Electric Vehicle, EV)因其环保特性而受到广泛关注。永磁同步电机(Permanent Magnet Synchronous Motor, PMSM)由于其高效率、高功率密度和良好的动态响应性能,在电动汽车驱动系统中得到了广泛应用。矢量控制(Field-Oriented Control, FOC)是实现PMSM高性能控制的关键技术之一,它能够实现对电机转矩和磁场的独立控制,从而达到类似直流电机的控制效果。本文将详细介绍如何使用来构建一个。

MHD0815的博客 1万+

YOLOv8 交通违规检测各个场景的实际应用

本文介绍了基于YOLOv8的交通违规检测系统在不同场景下的应用实现。系统可检测闯红灯、超速、违停和不系安全带等多种违规行为,针对每种场景提供了具体的技术方案和Python实现代码。其中闯红灯检测结合信号灯状态分析,超速检测通过距离时间计算速度,违停检测采用长时间跟踪策略,安全带检测则需更高精度识别。文章还展示了如何整合各功能构建综合交通监管系统,并总结了不同应用场景的技术要点和优化方向,为智能交通管理提供了实用解决方案。

u010117029的博客 300

redis缓存穿透、缓存击穿、缓存雪崩等缓存在高并发和安全压力下的一些问题解决方案--redis分布式锁:set px nx、Redisson的实现-java代码层控制分布式锁

文章目录 1、缓存击穿 是某一个热点key在高并发访问的情况下,突然失效,导致大量的并发打进mysql数据库的情况 解决:在正常的访问情况下,如果缓存失效,如果保护mysql,重启缓存的过程 使用redis数据库的分布式锁,解决mysql的访问压力问题 2、缓存穿透 是利用redis和mysql的机制(redis缓存一旦不存在,就访问mysql),直接绕过缓存访问mysql,而制造的db请求...

weixin_44185736的博客 1286

在Ubuntu上安装Node.js编程

在Ubuntu操作系统上安装Node.js是非常简单的,本文将为您提供详细的安装步骤。这是一个简单的Node.js HTTP服务器示例,它将在本地主机的端口3000上监听请求,并返回"Hello, World!npm是Node.js的包管理器,您可以使用它来安装和管理Node.js模块。您已成功在Ubuntu上安装了Node.js,并创建并运行了一个简单的Node.js应用程序。现在,您已经成功安装了Node.js和npm,让我们创建一个简单的Node.js应用程序并运行它。如有任何疑问,请随时提问。

CodeNexus的博客 3524

一文彻底分清缓存穿透、缓存击穿、缓存雪崩问题(含记忆技巧)

缓存穿透是指用户请求的数据在缓存中不存在即没有命中,同时在数据库中也不存在,导致用户每次请求该数据都要去数据库中查询一遍。如果有恶意攻击者不断请求系统中不存在的数据,会导致短时间大量请求落在数据库上,造成数据库压力过大,甚至导致数据库承受不住而宕机崩溃。那么,我们该怎么记忆缓存穿透呢?我们可以这么想,缓存穿透其实就是恶意攻击,就是有人想“穿”过你的防护网(缓存)来“偷”你的家(数据库),这也就是穿透。或者你这样想,有人想恶意攻击你的数据库,这是不是不好的行为,是不是小偷的行为!

胜人者有力,自胜者强! 1万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part5(四种类型缓存异常【缓存雪崩、击穿、穿透】、四种解决异常的方案、常见问题之三高、Redis 的热key问题、复制)~整起

java基础巩固-宇宙第一AiYWM:为了维持生计,Redis基础Part5(四种类型缓存异常、四种解决异常的方案)~整起

https://ywmhhbaiminminai.github.io/categories/ 1000

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Redis 缓存穿透、缓存雪崩、缓存击穿

缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。常见的解决方案有两种:缓存空对象优点:实现简单,维护方便缺点: 额外的内存消耗 可能造成短期的不一致(恶意攻击的对象id对应的redis空值缓存失效前成为了新插入的id,造成真实客户只能得到空缓存)布隆过滤(类似于位示图0、1代表是否存在)优点:内存占用较少,没有多余key缺点: 实现复杂 存在误判可能(对于过滤结果:假的一定为假,真的有小概率为假)

weixin_53535434的博客 1199

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Redis100篇 - Redis最常用场景:缓存怎么用 缓存穿透/击穿/雪崩解决方案

Redis缓存穿透问题及解决方案 摘要:Redis作为高性能内存数据库,广泛应用于缓存场景以提升系统性能。本文重点分析了Redis缓存使用中的关键问题——缓存穿透,即频繁查询不存在的数据导致数据库压力剧增。当请求无法在缓存命中时,会直接访问数据库,若数据不存在则无法缓存,形成恶性循环。解决方案包括:1)缓存空值策略,即使查询结果为null也将其缓存并设置较短过期时间,避免重复穿透;2)通过Java代码示例展示了在Spring Boot项目中如何实现这一防护机制。该方案能有效拦截恶意请求,保护数据库资源,确保

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

面试必问——Redis 缓存 三兄弟(穿透,击穿,雪崩)一文讲清楚

给某一个key设置了过期时间,当key过期的时候,恰好这个时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮。:逻辑过期(不给数据加过期时间,而是在value中维护一个expire逻辑过期时间,有线程来查询数据时,判断数据是否过期,过期则。:实现比较复杂,存在误判(误判率是可以调节的,数组长度越长,误判率越低,但是对应的内存消耗也越大)的数据,mysql查询不到数据也不会写入缓存,就会导致每次请求都查数据库。:缓存空数据,查询返回的数据为空,仍把这个空结果进行缓存。

2301_79966297的博客 652

java面试八股文Day1-缓存穿透,缓存击穿,缓存雪崩

本文融合小林coding,JavaGuide,面试鸭,Gemini,ChatGpt等多个平台上的资料

2401_87669378的博客 183

Redis缓存穿透,缓存击穿,缓存雪崩解决方案以及封装Redis工具类

参考自黑马程序员 缓存穿透 缓存穿透: 数据在数据库和redis中都不存在,请求直接打在数据库中。 解决方案: 方案一: 方案二: 代码案例实现: // 缓存穿透 private Shop cacheBreakDown(Long id){ // 查询redis String jsonShop = (String) redisTemplate.opsForValue().get(RedisConstants.SHOP_CACHE + id); .

weixin_44991304的博客 1021

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

缓存击穿,缓存穿透,缓存雪崩概念以及解决方法

weixin_65685799的博客 129

缓存穿透、击穿、雪崩,这样回答要满分呀!

缓存穿透、缓存击穿、缓存雪崩是经典的老八股文啦,之前去面试一个银行,就被问到啦,本文跟大家聊聊怎么回答哈~~缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。通俗点说,读请求访问时,缓存和数据库都没有某个值,这样就会导致每次对这个值的查询请求都会穿透到数据库,这就是缓存穿透。

cxytony的博客 163

Redis从理论到实战:用Redis解决缓存穿透、缓存击穿问题(提供解决方案)

缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远都不会生效,这些请求都会打到数据库。当有人恶意频繁地访问在缓存中和数据库中都不存在的数据时,整个系统就可能出现问题。缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。2、解决方案常见的解决方案有两种:互斥锁和逻辑过期。互斥锁:当线程1查询缓存未命中时,会获取一个互斥锁,然后查询数据库并重建缓存数据;

竹林幽深 211

Java-Redis缓存穿透,击穿,雪崩和布隆算法

假设一个客户端 一个tomcat 一个redis(里面有一条热门数据 时间期限为1天) mysql1天之内 是客户端---- tomcat ----redis1天之后 客户端----tomcat----mysql 这种情况就叫缓存击穿总结: redis中只有一条有效数据,当过了这个时间,tomcat就穿过redis,直接访问数据库,这个就叫缓存击穿缓存击穿和缓存穿透的区别:缓存击穿是缓存穿透的一种特殊表现形式。

搬着砖,敲着代码的博客 1027

【从零开始——Redis 进化日志|Day6】缓存的三剑客:穿透、击穿、雪崩,到底怎么防?(附生产级代码实战)

面试官:穿透、击穿、雪崩都分不清,你敢说精通 Redis?

Tjy2186987211的博客 1004

说说什么是Redis缓存击穿、缓存穿透、缓存雪崩?

Redis缓存常见问题解析:本文介绍了Redis使用中的三种典型问题:缓存击穿(热点数据失效导致数据库压力)、缓存穿透(请求不存在数据导致无效查询)和缓存雪崩(大量缓存同时失效)。针对这些问题,文章提供了Java实现方案:使用分布式锁防止击穿,布隆过滤器避免穿透,以及随机过期时间预防雪崩。通过具体代码示例,展示了如何构建更健壮的Redis缓存机制,有效提升系统性能和可靠性。

xh2277659985的博客 209
上一篇: 解决idea start failed:异常key com.tang.intellij.lua.luacheck.LuaCheckSettings
天道饶
博客等级 码龄8年 0粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值