云数据库 Redis 内存溢出报错 OOM command not allowed 怎么修复

文章导读
Redis 报错 OOM command not allowed 通常是因为实例内存使用量达到 maxmemory 上限且淘汰策略为 noeviction,导致写入被拒绝。修复核心是调整淘汰策略为 allkeys-lru 或 volatile-lru,或在确认物理内存充足后临时调大 maxmemory 阈值。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
  7. G 参考来源
A A

Redis 报错 OOM command not allowed 通常是因为实例内存使用量达到 maxmemory 上限且淘汰策略为 noeviction,导致写入被拒绝。修复核心是调整淘汰策略为 allkeys-lru 或 volatile-lru,或在确认物理内存充足后临时调大 maxmemory 阈值。

先说结论:该错误是 Redis 的主动保护机制,并非一定代表物理内存耗尽,而是触发了写入拒绝策略。

  • 先确认:执行 INFO memory 检查 used_memory 与 maxmemory 比值及内存碎片率。
  • 先处理:将 maxmemory-policy 从 noeviction 改为 allkeys-lru 或 volatile-lru 以允许驱逐。
  • 再验证:执行 SET 命令测试写入是否恢复,并监控 evicted_keys 指标确认淘汰生效。

命令速用版

以下命令可用于快速诊断和临时修复,需具备 CONFIG 权限:

# 查看内存使用与限制
INFO memory
# 查看当前淘汰策略
CONFIG GET maxmemory-policy
# 修改淘汰策略为允许驱逐
CONFIG SET maxmemory-policy allkeys-lru
# 临时调大内存上限(单位字节,重启失效)
CONFIG SET maxmemory 2147483648

为什么会这样

根本原因是 Redis 当前内存使用量达到配置的最大限制,且配置的淘汰策略不允许删除任何键。

当 maxmemory-policy 为 noeviction(默认值)时,Redis 为了保护数据完整性,在 used_memory 达到 maxmemory 后会拒绝所有可能增加内存的写命令(如 SET、LPUSH、PUBLISH),但读命令仍可正常执行。此外,内存碎片率过高(mem_fragmentation_ratio > 1.5)可能导致操作系统实际分配内存远超 Redis 统计值,触发底层分配失败。

分步处理

按以下顺序排查并修复,避免盲目扩容导致系统崩溃:

1. 确认内存状态
执行 INFO memory,对比 used_memory_human 和 maxmemory_human。若 used_memory 接近 maxmemory 且碎片率低于 1.5,确认为逻辑内存满。

云数据库 Redis 内存溢出报错 OOM command not allowed 怎么修复

2. 调整淘汰策略
执行 CONFIG SET maxmemory-policy allkeys-lru。若业务依赖 TTL,可选 volatile-lru。此操作立即生效,无需重启,但不会自动删除现有数据,仅在新写入触发上限时开始淘汰。

3. 检查权限与配置
若 CONFIG 命令报错 Permission denied,检查 ACL 权限或云数据库控制台是否禁止动态配置。云数据库通常需在控制台调整参数组。

4. 清理大 Key
若无法调整策略,使用 redis-cli `--bigkeys` 扫描大 Key 并手动删除,释放空间。

怎么验证是否生效

执行 SET test_key "value" 命令,若不再返回 OOM 错误则修复成功。

再次执行 INFO stats,观察 evicted_keys 数值是否开始增长,增长表示淘汰策略正在工作。同时监控 INFO memory 中的 used_memory 是否稳定在 maxmemory 附近。

常见坑

1. 碎片率过高误判
若 mem_fragmentation_ratio > 1.5,单纯调大 maxmemory 可能加剧碎片,建议重启实例或开启内存碎片整理。

云数据库 Redis 内存溢出报错 OOM command not allowed 怎么修复

2. 集群节点局部超限
Redis Cluster 环境中,报错可能仅发生在单个分片节点。需逐个节点检查内存,而非仅看集群总览。

3. 配置不持久
CONFIG SET 修改的参数重启后失效。生产环境需同步修改 redis.conf 或云数据库参数组配置。

4. 客户端缓冲区溢出
大量订阅发布(PUB/SUB)可能导致 client-output-buffer-limit 占满内存,需单独配置缓冲区限制。

常见问题

读操作也会报 OOM 吗?

不会。OOM command not allowed 仅针对写操作,GET 等读命令在内存满时仍可正常执行。

修改 maxmemory 需要重启 Redis 吗?

不需要。CONFIG SET maxmemory 动态生效,但重启后会还原为配置文件中的值。

云数据库无法执行 CONFIG 命令怎么办?

云厂商通常禁用 CONFIG 命令。需登录云控制台,在实例参数设置中修改 maxmemory 和淘汰策略。

参考来源

  • CSDN 博客:Redis 报 OOM command not allowed 是内存满了吗?
  • CSDN 博客:Redis 内存溢出 (OOM) 排查与恢复实战
  • 技术文档:Redis 常见故障解决方案
  • CSDN 问答:OOM:为何 Redis 提示 command not allowed?