尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Redis 从 0 到 1(二十二):一个 500MB 的 Hash 拖垮实例——bigkey 的 Go 渐进删除
我不会起名字322· 后端 / 算法 / 数据库 技术栈 力扣 Hot100 Go 项目 Redis MySQL文章目录Redis 从 0 到 1二十二一个 500MB 的 Hash 拖垮实例——bigkey 的 Go 渐进删除一、现象一条 DEL实例阻塞 3 秒二、bigkey 的 4 类成因收藏点 1三、找出 bigkey收藏点 2四、Go 实操渐进删除收藏点 3五、治理 Checklist收藏点 4六、排查步骤怀疑有 bigkey七、总结Redis 从 0 到 1二十二一个 500MB 的 Hash 拖垮实例——bigkey 的 Go 渐进删除上一篇《Redis 从 0 到 1二十一P99 涨到 80ms慢查询日志 5 步定位法 Go 采集器》我们学会了抓慢命令链接https://blog.csdn.net/2501_92769340/article/details/167399878 。本篇处理慢命令最常见的元凶bigkey——怎么找、怎么安全删、怎么预防。一、现象一条 DEL实例阻塞 3 秒运维同学清理一批历史数据脚本里对几百个 key 执行 DEL。其中一个是 500MB 的 Hash某活动的用户报名表。DEL 是同步释放内存Redis 主线程遍历整个 Hash 结构逐个释放——3 秒里实例不响应任何请求上游全部超时。更糟的是这样的 key 往往不止一个。bigkey 的危害不止 DEL操作bigkey 下的表现HGETALL / SMEMBERS全量返回网络 序列化 客户端内存三杀DEL / HDEL 大批量同步释放阻塞主线程主从复制全量同步时大 key 拖慢传输backlog 被冲掉第 8 篇来源 2AOF 重写 / RDB处理大 value 耗时翻倍二、bigkey 的 4 类成因收藏点 1成因典型现场预防无上限集合消息列表、日志队列只增不删LTrim / 定期归档 / Stream MAXLEN第 17、18 篇单个 value 过大把整个 JSON 数组100 万条订单明细塞一个 String拆 key 分页存list:1001:page:1基数失控的 HashHash 存全部商品 id → 信息商品涨到百万级按前缀拆 Hash分桶批量导入未分批一次性导入 500 万 key 的单 value 很大分批 每批验大小三、找出 bigkey收藏点 2# 方法 1采样统计生产常用低侵入redis-cli--bigkeys# 每种类型最大的 key采样估算redis-cli--memkeys# 直接按内存排序Redis 6.2更准确# 方法 2精确测量单个 keyMEMORY USAGE key:xxx[SAMPLES5]# 含内部结构开销的真实字节数MEMORY USAGE key:xxx SAMPLES50# 大 Hash/Set 增加采样数更准OBJECT ENCODING key:xxx# 看编码hashtable 通常意味着大# 方法 3离线全量分析最准从库或 RDB 上做rdb-cmemory dump.rdbmem.csv# 工具github.com/sripathikrishnan/redis-rdb-tools判多大算 bigkey经验阈值——String 100KB、集合类 5000 个元素或 10MB就该警惕结合实例内存看8GB 实例和 256GB 实例标准不同。四、Go 实操渐进删除收藏点 3大 String 用 UNLINK异步释放立即返回大集合类用 SCAN 家族分批删packagemainimport(contextfmttimegithub.com/redis/go-redis/v9redis-0to1/redisx)// DeleteBigHash 渐进删除大 HashHSCAN 分批 HDEL每批之间主动让出主线程funcDeleteBigHash(ctx context.Context,rdb*redis.Client,keystring,batchint64)error{varcursoruint64for{// 1. 扫一批 fieldfields,next,err:rdb.HScan(ctx,key,cursor,*,batch).Result()iferr!nil{returnfmt.Errorf(HSCAN 失败: %w,err)}// 2. 分批删这批 fieldPipeline 打包iflen(fields)0{pipe:rdb.Pipeline()fori:0;ilen(fields);i2{// HScan 返回 field,value 交替pipe.HDel(ctx,key,fields[i])}if_,err:pipe.Exec(ctx);err!nil{returnfmt.Errorf(HDel 批次失败: %w,err)}}cursornextifcursor0{break}// 3. 主动让出主线程每批删完歇 10ms实例继续服务time.Sleep(10*time.Millisecond)}returnnil}// DeleteBigSet / DeleteBigZSet 同理SSCANSREM / ZSCANZREM模板相同funcmain(){rdb,err:redisx.NewClient(redisx.Config{Addr:127.0.0.1:6379,Password:redis123,PoolSize:10})iferr!nil{panic(err)}ctx:context.Background()key:activity:signup// 先量一下有多大usage,_:rdb.MemoryUsage(ctx,key,0).Result()fmt.Printf(%s 占用 %d 字节\n,key,usage)// String 类型的大 keyUNLINK 一步搞定后台线程异步释放t,_:rdb.Type(ctx,key).Result()iftstring{rdb.Unlink(ctx,key)}elseifthash{DeleteBigHash(ctx,rdb,key,500)}fmt.Println(删除完成实例无感)}要点UNLINK 优先Redis 4 的 UNLINK 把释放动作交给后台线程主线程只做摘除大 String 场景一步到位SCAN 家族分批HSCAN/SSCAN/ZSCAN 每批只碰一小部分内存配 HDEL 精确删批间 sleep 让出删 500 个 field 约 1mssleep 10ms 是让单线程喘口气服务别的请求删完验证EXISTSMEMORY USAGE并回看 slowlog 确认无新慢命令。五、治理 Checklist收藏点 4上线前redis-cli --bigkeys进巡检脚本每周跑应用侧所有可能无限增长的集合都设上限LTrim / MAXLEN / 定期归档删除侧禁止 DEL 大 keyString 用 UNLINK、集合用渐进删配置侧lazyfree-lazy-user-del yes——把 DEL 全局改成 UNLINK 语义防手滑监控侧slowlog 采集器第 21 篇 MEMORY USAGE 抽查双保险六、排查步骤怀疑有 bigkeyslowlog 找耗时异常的全量读命令HGETALL/SMEMBERS拿到 keyMEMORY USAGE key确认大小OBJECT ENCODING看编码OBJECT REFCOUNT 从库DEBUG OBJECT看 serializedlength交叉验证按第三节模板渐进删除删完复核 slowlog。七、总结bigkey 的罪不在大在对它做的操作都是 O(N) 且单线程执行找–bigkeys 采样 MEMORY USAGE 精确删UNLINKString/ SCAN 家族分批删集合类批间让出主线程防集合设上限、DEL 改 UNLINK 语义、巡检常态化。下一篇预告bigkey 是大的问题下一篇是热的问题——下一篇《一个热 key 打到 10 万 QPS——hotkey 与本地缓存的 Go 实现》单槽热点的解法是二级缓存。
RELATED

相关推荐

【Git】从入门到精通(十一)—— git reset 三种模式详解

【Git】从入门到精通(十一)—— git reset 三种模式详解

一、git reset 的作用 在深入三种模式之前,我们先搞清楚 git reset 到底在做什么。 git reset 的核心作用是:移动 HEAD 指针和当前分支指针,并可选地影响暂存区和工作区。 回顾一下 Git 的三大区域: 工作区(Workin…

📅 2026/11/5 5:16:19
MarkItDown 实战指南:一条命令把 PDF、Word、PPT 转成 Markdown,扫描件也能提字

MarkItDown 实战指南:一条命令把 PDF、Word、PPT 转成 Markdown,扫描件也能提字

MarkItDown 实战指南:一条命令把 PDF、Word、PPT 转成 Markdown,扫描件也能提字 【免费下载链接】markitdown Python tool for converting files and office documents to Markdown. 项目地址: https://gitcode.com/GitHub_Trending/ma/markitdown …

📅 2026/11/5 5:16:19
MAS 免费激活脚本:一条命令搞定 Windows 与 Office,离线内网照样能激活

MAS 免费激活脚本:一条命令搞定 Windows 与 Office,离线内网照样能激活

MAS 免费激活脚本:一条命令搞定 Windows 与 Office,离线内网照样能激活 【免费下载链接】Microsoft-Activation-Scripts Open-source Windows and Office activator featuring HWID, Ohook, TSforge, and Online KMS activation methods, along with adv…

📅 2026/11/5 5:16:19
MORE NEWS

更多资讯

📰

2KB SRAM Arduino多任务:SCoop协作式调度实战

简介:面向Arduino开发者与单片机并发编程学习者的SCoop多线程库完整源码包,适合在资源受限的AVR等平台上组织多任务、提升程序响应与执行效率。压缩包共58个文件、约726KB,以29个ino示例、12个txt说明与变更日志、7个h头文件、7个cpp实现为主…

📰

研究生查文献总漏关键论文?我更建议用 NNScholar 接着做引文追踪

关键词换了一轮又一轮,搜出来的论文还是那几篇;等读到一篇真正贴近课题的文章,又发现它引用的方法、讨论的争议,自己之前都没搜到。 这时,我更建议先停一下:别急着换第十组关键词,先沿着这篇核…

📰

VMware安装CentOS 7全流程指南与优化技巧

1. 环境准备与工具选择在开始安装CentOS 7之前,我们需要做好充分的准备工作。VMware Workstation作为业界领先的虚拟化软件,其15.x及以上版本对CentOS 7有着最好的兼容性支持。我推荐使用VMware Workstation 16 Pro,它不仅支持最新的硬件虚拟…

📰

Remix IDE与Polkadot Hub智能合约部署指南

1. 项目概述:Remix IDE Polkadot Hub 智能合约部署实战 作为区块链开发者入门的第一个里程碑,能够独立完成智能合约的部署至关重要。今天我要分享的是如何用浏览器端的Remix IDE,在Polkadot Hub测试网上部署一个基础的Solidity合约。这个方…

📰

纯电动车节能车速规划:时空建模与动态调整策略

1. 纯电动汽车经济性车速规划的核心挑战作为一名在新能源汽车领域深耕多年的工程师,我亲历了无数次纯电动车在复杂城市路况下的能耗测试。最让我印象深刻的是去年在北京三环路上的一次实测:同一辆电动车,在不同驾驶策略下能耗差异高达23%。这…

📰

数据清洗技术演进:从批处理到智能化的实践历程

1. 数据清洗技术的起源与早期发展数据清洗这个概念最早可以追溯到上世纪60年代数据库技术诞生初期。当时IBM研究员Edgar F. Codd提出关系型数据库理论时,就已经意识到数据质量问题的重要性。我在早期参与银行系统建设时,就遇到过由于手工录入错误导致账户…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬