0

0

Redis如何构建多级缓存抗住雪崩流量

P粉602998670

P粉602998670

发布时间:2026-03-15 10:33:31

|

187人浏览过

|

来源于php中文网

原创

缓存穿透时应写入空值占位:DB查无结果则setex key 60 "NULL",应用层识别后转null;本地缓存同理用Optional.empty(),避免重复查询。

redis如何构建多级缓存抗住雪崩流量

缓存穿透时 get 返回 null 怎么办

Redis 本身不区分“缓存未命中”和“业务数据确实为空”,get 拿不到就直接穿透到 DB。这在多级缓存里会放大问题——比如本地缓存(Caffeine)也查不到,请求全涌向 Redis,再涌向 DB。

解决思路不是加锁或布隆过滤器优先,而是统一用空值占位:

  • DB 查无结果时,写入 setex key 60 "NULL"(TTL 缩短,避免长期污染)
  • 应用层读到 "NULL" 字符串,主动转成 null 或业务空对象,不继续往下查
  • 本地缓存同理:cache.put(key, Optional.empty()),别让它反复问 Redis

注意:别用 ""0 占位,容易和真实业务值混淆;也别设过长 TTL,60 秒足够覆盖大部分热点空查场景。

本地缓存和 Redis 的 TTL 怎么配才不互相打架

两级缓存的 TTL 如果随便设,会出现“本地还没过期,Redis 已更新,结果读到脏数据”或者“本地刚过期,Redis 也过期,瞬间打穿 DB”。

关键不是同步,而是错峰 + 主动刷新:

  • 本地缓存 TTL 设为 Redis 的 70%(比如 Redis 是 300s,本地设 210s),让它先过期,触发一次 Redis 查询
  • 查询 Redis 后,立刻用新值+新 TTL 刷新本地缓存(不是等下次访问才加载)
  • Redis 的 TTL 要带随机偏移,比如 300 ± 30,防止大量 key 同时失效引发雪崩

别依赖 expire 精确控制——Redis 过期是惰性+定期混合策略,实际失效时间有浮动。

并发重建缓存时 setnx + expire 为什么还是失败

setnx 成功但 expire 失败,会导致 key 永不过期,后续所有请求都卡在空值等待,这是经典竞态漏洞。

小微助手
小微助手

微信推出的一款专注于提升桌面效率的助手型AI工具

下载

必须原子操作:

  • Redis 2.6.12+ 用 set key value ex 300 nx,一条命令搞定
  • 老版本只能用 Lua 脚本:redis.call("set", KEYS[1], ARGV[1], "EX", ARGV[2], "NX")
  • 本地缓存层也要做类似保护:Caffeine 的 refreshAfterWriteexpireAfterWrite 更适合抗抖动,它不阻塞读,后台异步刷新

别图省事拆成两步命令,网络分区或进程中断时,setnx 成功但 expire 没发出去,这个 key 就永远卡死。

流量突增时,本地缓存击穿比 Redis 击穿更危险

很多人盯着 Redis 是否扛得住,却忽略本地缓存(如 Caffeine)在单机 QPS 上千时,如果没限流,一个 key 击穿可能瞬间拉起上百个线程查 DB——而 Redis 集群还能分摊,单机本地缓存没有兜底。

必须在本地缓存层加轻量熔断:

  • Caffeine.newBuilder().maximumSize(10000).recordStats() 开启统计,监控 evictionCountmissRate
  • 对高危 key(比如用户中心、商品详情),封装一层 loadingCache.get(key, k -> loadWithSemaphore(k)),用信号量限制并发加载数
  • 别让本地缓存“自动加载”失控——CacheLoader 必须包裹异常兜底,否则一次 DB 超时可能导致整个缓存 loader 停摆

最易被忽略的是:本地缓存的 GC 压力。大对象频繁 put/remove 会触发 Young GC,反而拖慢响应——key 对应的 value 要尽量小,别把整张订单 JSON 塞进去。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

457

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

549

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

337

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

82

2025.09.10

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1111

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号