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,确认为逻辑内存满。
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 可能加剧碎片,建议重启实例或开启内存碎片整理。
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?