
线上 Redis 内存使用率持续上升,常见表现是:写入变慢、命令延迟抖动、客户端出现 OOM command not allowed 报错,或者淘汰策略清掉了不该清的数据。本文按"先看整体、再找大 key、最后看策略与碎片"的顺序给出一套可复现的排查流程。
redis-cli INFO memory重点关注:
used_memory:分配器分配的内存,是数据集实际占用的近似值。used_memory_rss:操作系统视角下进程占用的物理内存。mem_fragmentation_ratio:rss / used_memory。明显大于 1.5 说明碎片较多;小于 1 通常意味着发生了 swap,需要立即处理。maxmemory 与 maxmemory_policy:是否设置了上限,以及达到上限后的行为。如果 used_memory 本身很高,说明数据太多;如果只是 rss 高而 used_memory 不高,则重点看碎片。
--bigkeys 基于 SCAN 采样,对线上影响较小:
redis-cli --bigkeys -i 0.1-i 0.1 表示每次扫描间隔 0.1 秒,用来降低对业务的干扰。也可以用 --memkeys 按内存大小统计。找到可疑 key 后,确认单个 key 的真实占用:
redis-cli MEMORY USAGE user:feed:10086 SAMPLES 5
redis-cli TYPE user:feed:10086
redis-cli LLEN user:feed:10086注意:不要在生产环境使用 KEYS *,它会阻塞单线程;需要遍历时使用 SCAN 并带上 COUNT。
直接 DEL 一个包含几百万元素的集合会阻塞主线程。Redis 4.0 起提供异步删除:
redis-cli UNLINK user:feed:10086UNLINK 先把 key 从键空间摘除,内存回收交给后台线程。对于仍需保留的大集合,更好的做法是业务侧拆分,例如按用户 ID 取模分桶,把一个大 hash 拆成多个小 hash。
很多内存问题来自没有设置过期时间。可以抽样检查:
redis-cli --scan --pattern 'session:*' | head -n 20 | xargs -I{} redis-cli TTL {}TTL 返回 -1 表示永不过期。再确认淘汰策略:
redis-cli CONFIG GET maxmemory-policynoeviction:达到上限后写入直接报错,适合不能丢数据的场景。allkeys-lru / allkeys-lfu:对所有 key 淘汰,适合纯缓存。volatile-*:只淘汰设置了过期时间的 key;如果大部分 key 没有 TTL,这类策略起不到作用,内存仍会写满。当 mem_fragmentation_ratio 长期偏高且 used_memory 不高时,可在 Redis 4.0+ 开启在线整理:
redis-cli CONFIG SET activedefrag yes该功能依赖 jemalloc 构建,并会消耗一定 CPU,建议先在低峰期观察 INFO memory 与延迟指标。若实例是托管服务,参数是否可调以控制台为准。
Redis 内存问题多数不是内存不够,而是 key 设计与生命周期管理缺失:大 key 没拆、TTL 没设、策略不匹配。把上述检查固化为巡检脚本,并在云监控中对内存使用率、碎片率、慢日志数量设置告警,可以在故障发生前发现趋势。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。