news 2026/9/3 1:04:26

java - redis 缓存穿透

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
java - redis 缓存穿透

一、缓存穿透

定义

查询一个数据库里面根本不存在的数据

Redis 查不到 → 去查 MySQL;MySQL也查不到。
缓存永远不会生效,每一次请求都会直接打到数据库。

举例子:
商铺 id 数据库最大只有 10,但是有人疯狂请求id=-1id=99999

  1. Redis:cache:shop:-1不存在 → 返回null
  2. 代码去查 MySQL,数据库没有这条记录,返回null
  3. 不会往Redis存任何东西
  4. 下一次再来请求-1,流程又重复一遍,又访问数据库

如果恶意发起成千上万次这种不存在 id 的请求,数据库压力直接被打崩,这就是缓存穿透

区分记忆:

  • 缓存击穿:数据是存在的,只是缓存刚好过期
  • 缓存穿透:这条数据压根就不存在于数据库

解决方法1:缓存空值(小项目首选)

核心思路

数据库查不到数据时,向Redis存一个空字符串"",并且设置一个短过期时间(2分钟)

下次再来相同请求:
Redis拿到"",直接返回失败,不再访问数据库

你项目里面对应的核心代码

@OverridepublicResultqueryById(Longid){// 1. 从 redis 查询商铺缓存Stringkey=CACHE_SHOP_KEY+id;StringshopJson=stringRedisTemplate.opsForValue().get(key);// 2. 判断是否存在,有真实的商铺JSON数据if(StrUtil.isNotBlank(shopJson)){// 3. 存在,直接返回Shopshop=JSONUtil.toBean(shopJson,Shop.class);returnResult.ok(shop);}// 判断命中的是否是空值【解决:缓存穿透】// shopJson 不是 null,但却是 "" 空字符串(命中空缓存)if(shopJson!=null){// 说明 Redis 存了空字符串,代表缓存不存在returnResult.fail("商铺不存在");}// 4. 缓存未命中,查询数据库// 只有 shopJson == null 的时候,才能跑到这里Shopshop=getById(id);// 5. 数据库没查到if(shop==null){// 写入空值,过期时间 2 分钟stringRedisTemplate.opsForValue().set(key,"",CACHE_NULL_TTL,TimeUnit.SECONDS);returnResult.fail("商铺不存在");}// 6. 查询到数据,写入 RedisstringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL,TimeUnit.MINUTES);// 返回结果returnResult.ok(shop);}# 什么时候会进到数据库查询(shopJson==null1.第一次访问这个id,Redis里面还没有创建任何key;2.之前存的空字符串 `""` 过期了,Redis自动把这个key删掉了;3.Redis缓存被手动清空。

✅优点:简单好实现
❌缺点:Redis会存很多没用的空key,占用一点点内存

方案2:布隆过滤器(海量大数据场景)

思路

提前把数据库所有合法id全部放进布隆过滤器。
请求进来,先经过布隆过滤器校验

  • 如果过滤器判定:id不存在 → 直接拦截,Redis、数据库都不去访问
  • 如果过滤器判定:id存在 → 才放行,查询缓存、数据库

✅优点:完全拦截无效请求,不会产生大量空key
❌缺点:实现复杂;布隆过滤器有极小误判概率;新增数据要维护过滤器;小型项目一般不用

方案3:接口参数校验(第一道防线)

在最开始就拦截非法参数,不往下走缓存逻辑
比如:商铺id必须大于0

if(id<=0){returnResult.fail("id非法");}

三、快速区分三大缓存问题

问题本质解决方案
缓存穿透查询不存在的数据,每次请求直达数据库缓存空值、布隆过滤器、参数校验
缓存击穿热点key缓存过期,大量并发同时打到数据库互斥锁、逻辑过期
缓存雪崩大批量缓存key同时过期,数据库压力瞬间暴涨过期时间加上随机偏移值
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 1:02:17

AI Agent开发必懂:Skill、MCP、子Agent的区别与组合

最近很多人在群里聊 AI Agent 开发时&#xff0c;都会遇到一个共同的困惑&#xff1a;今天看文档说要给 Claude 写一个 Skill&#xff0c;明天看到某个项目在提 MCP Server 的配置&#xff0c;后天又听人说复杂任务要拆成子 Agent 去跑。这三个词听起来都跟“让模型更聪明”有关…

作者头像 李华
网站建设 2026/9/3 0:04:21

【原创】基于微信小程序+AI大模型+uni-app的宠物用品商城小程序(设计与实现)

摘要&#xff1a;随着电子商务与本地生活服务的普及&#xff0c;线上交易与店铺运营管理已成为常规业态。传统分散式进销存与人工对账方式存在流程割裂、库存难同步、促销规则难落地、经营数据难沉淀等弊端&#xff0c;难以支撑一体化的数字化运营。同类课题亦多见多商户在线商…

作者头像 李华
网站建设 2026/9/2 23:58:32

.NET WinForm仓储管理系统通用源码设计与实现

简介&#xff1a;这是一套基于.NET Framework的WinForm仓储管理系统通用源码&#xff0c;适合.NET初学者及需要快速搭建库存管理、出入库等业务模块的开发者。源码采用模块化分层设计&#xff0c;涵盖数据库管理、数据访问层&#xff08;DAL&#xff09;、业务逻辑层&#xff0…

作者头像 李华
网站建设 2026/9/2 23:58:31

资讯日报生成器实战:从Prompt到Agent工作流编排与落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华