应用写入Redis时返回 OOM command not allowed when used memory > 'maxmemory',但服务器执行 free -h 可能还有可用内存。这个现象并不矛盾,因为报错首先表示Redis达到了自己配置的内存上限,并且当前策略无法为这条写命令释放足够空间。
处理重点不是立即重启Redis,也不是随手把 maxmemory 改成0。先保留运行时配置、内存统计、淘汰计数和键空间证据,才能判断是数据集增长、过期策略失效、内存碎片,还是修改了错误的配置文件。

先确认错误来自哪一个Redis实例
同一服务器可能同时运行系统服务、容器和面板创建的多个Redis。先从应用连接配置确认主机、端口和数据库,再在目标实例执行:
redis-cli -h 127.0.0.1 -p 6379 PING
redis-cli -h 127.0.0.1 -p 6379 INFO server
认证信息不要直接写进共享命令记录或截图。容器环境还要核对端口映射和容器内配置,避免查到了本机另一个空实例。
后续所有证据必须来自应用实际连接的同一实例。 只看服务器总内存,无法解释Redis自己的 maxmemory 边界。
读取运行时上限和淘汰策略
先查看Redis当前真正生效的配置:
redis-cli CONFIG GET maxmemory
redis-cli CONFIG GET maxmemory-policy
redis-cli INFO memory
redis-cli INFO stats
Redis官方文档说明,允许淘汰的策略会在达到上限时选择键释放空间;不允许淘汰或没有符合条件的键时,可能拒绝会继续占用内存的写命令。
重点记录 used_memory、used_memory_rss、maxmemory、mem_fragmentation_ratio、evicted_keys 和当前策略。配置值与预期不一致时,应先确认启动参数、配置文件和容器挂载,而不是直接修改应用代码。
区分数据集增长和内存碎片
used_memory 更接近Redis分配器统计的数据与内部结构,used_memory_rss 反映操作系统看到的常驻内存。两者差距明显时,可以把碎片或内存尚未归还给系统列为线索,但不能只凭一个比例下结论。
查看键空间和大键分布:
redis-cli INFO keyspace
redis-cli --bigkeys
--bigkeys 会扫描键空间,线上大实例应在低峰评估影响。真正需要回答的是哪些业务键在增长、有没有设置TTL、单键大小是否异常,以及增长时间是否与发布或流量变化一致。
过期键不等于会立刻释放
键设置了TTL,只说明它具备过期时间。短时间大量写入、过期时间设置错误,或业务不断刷新TTL,都可能让数据集在到期前先触及上限。
可以抽样检查TTL和业务前缀的键数量,并从应用代码确认写入策略。不要在生产环境对未知键批量执行删除,缓存、会话、限流和队列使用错误删除方式都可能直接影响业务。
evicted_keys 持续增加意味着Redis正在按策略淘汰键。对于纯缓存这可能符合设计,对于不能丢失的数据则是风险信号,不能为了消除OOM就随意切换到激进淘汰策略。
noeviction什么时候是合理选择
noeviction 达到上限后拒绝部分写入,适合数据不能被自动驱逐、希望由应用明确处理容量异常的场景。缓存业务更常使用允许淘汰的策略,但选择哪一种取决于键是否可重建、是否设置TTL以及业务能否接受命中率下降。
把 noeviction 改成某个淘汰策略可能马上恢复写入,同时也意味着Redis开始主动删除键。修改策略前必须明确哪些数据允许消失。 这不是单纯的性能参数,而是数据行为选择。
运行时执行 CONFIG SET 可以用于受控验证,但不一定会持久写回启动配置。重启后恢复旧值,通常说明只改了运行时或配置写回路径与实际启动文件不一致。
不要把maxmemory直接顶到物理内存
Redis之外还有操作系统、持久化、复制缓冲区、客户端输出缓冲和其他服务需要内存。把 maxmemory 设成服务器全部内存,可能让Redis不再先报自己的OOM,随后却被内核直接终止。
开启RDB或AOF时,后台保存和重写还会带来额外内存压力。应结合持久化方式、峰值写入、复制和历史RSS确定安全余量,而不是只按当前 used_memory 计算。
容量已经没有安全空间时,可以在 萤光云 建立相近配置复现数据增长,也可以使用按小时计费的 LightNode 保留短期对照实例。对照环境应使用脱敏样本或可重建数据,不能把生产密钥和完整用户数据直接复制过去。
最小改动应该落在哪里
数据集异常增长时,先修复键生命周期、前缀或写入逻辑,再按业务规则清理可确认的数据。缓存容量确实不足时,才评估提高 maxmemory、调整实例内存或采用合适淘汰策略。
每次只改变一个主要变量,并在变更前保存 INFO memory、INFO stats 和配置值。涉及删除、切换策略或重启时,应先确认持久化、主从角色和回滚方案。
单纯执行 FLUSHALL 虽然能迅速清空内存,却会删除所有数据库的键,是不可逆的高风险操作,不应当作为常规排查步骤。
用趋势和重启验证结果
修复后持续观察 used_memory、RSS、淘汰键数量、命中率和应用错误率。内存应在业务允许的范围内趋于稳定,写入不再返回OOM,缓存业务的命中率也不能因新策略明显失控。
最后核对持久配置,并在维护窗口完成一次受控重启。重启后 CONFIG GET 仍显示目标上限和策略,数据加载、主从同步与应用读写正常,才算配置真正生效。只在当前进程里临时恢复写入,不算验收通过。


