Redis 内存满了怎么办?我说“加内存”,面试官让我出去……
最近有个兄弟去面试,回来跟我吐槽,说面试官太刁钻了。 面试官问他:“假设线上的 Redis 内存报警了,使用率飙到了 95%,你第一反应怎么处理?” 这兄弟想都没想,直接说:“找运维申请扩容,加内存呗。” 面试官盯着他看了两秒,问:“那如果扩容后又满了呢?一直加下去?公司预算是你家出的?” 这兄弟当场就卡壳了。 其实,这道题在面试里出现的频率非常高。它考察的不是你还会不会扩容,而是考察你有没有“治理思维”和“成本意识”。 今天我们就来聊聊,当 Redis 内存告急时,除了“加钱”,我们还能做什么。 很多时候,内存满是因为配置没设好。 Redis 有一个关键参数叫 很多公司默认配置是 所以,你首先要检查的是:我们是不是存了太多根本不用的数据? 如果你的业务允许数据丢失(比如只是做缓存),应该把策略调整为 改成 LRU 策略后,Redis 会自动把那些很久没人访问的冷数据清理掉,内存水位自然就降下来了。 如果淘汰策略已经开了,内存还是降不下来,或者业务要求数据不能随便丢,那就要找原因了:到底是什么东西占用了这么多内存? 通常有两种情况: 怎么找?千万别在生产环境直接敲 你应该用 Redis 自带的工具: 或者在 Redis 4.0 以后,使用 找到这些大 Key 后,通常会发现: 找到大 Key 了,比如一个叫 很多人的直觉反应是: 千万别这么干! Redis 是单线程处理命令的。删除一个 2GB 的 Key,意味着 Redis 要在主线程里一次性释放这 2GB 的内存空间。这个过程非常耗时,可能需要几百毫秒甚至几秒。 在这几秒钟里,Redis 无法处理任何其他请求(比如用户的登录、下单),这就叫“阻塞”。 正确的做法是使用 如果你的 Redis 版本很老,不支持 UNLINK,那就必须“分批删除”。比如是 Hash,就用 最后,要从源头解决问题。 很多开发习惯不好,写代码时只管 一定要定个规矩:所有的缓存 Key,必须设置过期时间。 哪怕设长一点(比如 30 天)也比永不过期强。这样 Redis 才能利用 回到开头的面试题。如果再被问到“Redis 内存满了怎么办”,你可以按这个逻辑回答,绝对稳: 这样回答,既展示了技术深度,又体现了你对线上稳定性的敬畏。 ⚡️ 别把时间浪费在低效复习上 很多人复习抓不住重点。作为过来人,我分析了100+份大厂面试记录,将 Go/Java/AI 的核心考察点、高频题、易错点 浓缩进了一份 PDF。 不搞虚的,全是干货。 加我微信:wangzhongyang1993,备注 【面经】 免费发你,立即纠正你的复习方向,把时间用在刀刃上。 wangzhongyang.com 也欢迎大家直接访问我的官网,里面有Go / Java / AI 的资料,免费学习!第一步:别急着扩容,先看策略
maxmemory,决定了它能用多少内存。当数据量达到这个限制时,Redis 会怎么做?这就取决于另一个参数:maxmemory-policy(内存淘汰策略)。noeviction。这个策略的意思是:内存满了就不让写了,任何写入操作(SET、LPUSH 等)都会直接报错(OOM command not allowed),但读操作还能正常进行。这会导致线上业务直接不可用。allkeys-lru 或者 volatile-lru。第二步:谁占了内存?揪出 Big Key
keys *,这会导致 Redis 阻塞,整个服务卡死。redis-cli --bigkeysmemory usage 命令去抽查。第三步:怎么删?千万别用 DEL
user:rank:list 的列表,占用 2GB 内存。DEL user:rank:list。UNLINK 命令(Redis 4.0+):UNLINK user:rank:listUNLINK 是非阻塞的。它会把这个 Key 从键空间里摘除(逻辑删除),然后把释放内存的繁重工作丢给后台线程去慢慢做(物理删除)。这样就不会卡住主线程。HSCAN 每次扫 1000 个字段,分多次 HDEL 删掉。第四步:给 Key 加上过期时间
SET,不管 EXPIRE(过期时间)。结果就是数据只进不出,内存迟早要爆。volatile-lru 策略自动循环利用内存。总结:面试怎么答?
maxmemory-policy 是否合适,是不是因为默认的 noeviction 导致无法写入,建议改为 LRU 策略自动清理冷数据。--bigkeys 工具分析内存分布,找出占用巨大的异常 Key。UNLINK 异步删除,避免阻塞主线程。END