必须设maxmemory且不能为0或模糊单位:默认0即不限制,生产环境等同裸奔,OOM Killer会杀进程致数据全丢;单位须规范(如2gb而非2g),建议设为物理内存75%并显式配置淘汰策略,否则策略失效将导致OOM。

maxmemory必须设,且不能设为0或模糊单位
Redis默认maxmemory 0,即不限制内存使用——这在生产环境等于裸奔。物理内存耗尽后,Linux OOM Killer会直接杀掉Redis进程,数据全丢。单位也容易错:maxmemory 2g不被识别,会被当作0处理;maxmemory 2gb才合法(注意是gb,不是g)。另外,别写1024m这种模糊值,Redis按字节解析,1024m实际是1024字节。
建议值取物理内存的75%,比如机器有16GB内存,就设maxmemory 12gb。预留空间给复制积压缓冲区(repl-backlog-size)、客户端输出缓冲区、AOF重写fork时的写时复制开销——这些都不计入used_memory,但吃的是RSS真实内存。
maxmemory-policy不能依赖默认,必须显式配且验证
只设maxmemory不设maxmemory-policy,Redis不会自动淘汰,而是退回到版本相关的默认行为(高版本默认noeviction,但你没声明就等于没控制)。更危险的是:拼写错误如no-eviction、NoEviction、带空格或大小写混用,都会导致策略失效,Redis继续接收写入直到OOM Killer出手。
必须同时配置两行:
maxmemory 12gb-
maxmemory-policy noeviction(全小写、无空格、无连字符)
配完立刻验证:redis-cli CONFIG GET maxmemory-policy返回必须是noeviction;redis-cli INFO memory | grep used_memory确认used_memory稳定在设定值附近;如果evicted_keys在涨,说明策略根本没生效。
noeviction不是万能解,得配合应用层错误处理
选noeviction意味着Redis超限后所有写命令(SET、HSET、LPUSH等)会返回标准错误:(error) OOM command not allowed when used memory > 'maxmemory'。这不是网络异常,是主动拒绝,应用必须捕获这个错误并做降级或告警,不能当连接失败重试。
常见坑:
- SDK自动重试机制遇到OOM错误继续发请求,加剧问题
- 日志里只记“写入失败”,没提取
OOM关键字,监控漏告 - 误以为是Redis挂了,反复重启,结果每次启动都因AOF加载+RDB恢复又冲高内存
建议在业务代码中对OOM错误单独打标,触发立即告警,并记录当前used_memory和mem_fragmentation_ratio,用于判断是否真内存不足,还是内存碎片过高(比如mem_fragmentation_ratio > 1.5且used_memory远低于maxmemory)。
配置要落盘,CONFIG SET只是临时补丁
CONFIG SET maxmemory 12gb和CONFIG SET maxmemory-policy noeviction只对当前进程有效,重启就丢。生产环境必须写入redis.conf,再执行CONFIG REWRITE——它会安全地重写配置文件,保留注释结构,删掉无效行。别手动覆盖,也别用echo >> redis.conf追加,容易引发语法错误。
操作顺序要严格:
- 先编辑
redis.conf,加入两行配置 - 执行
redis-cli CONFIG REWRITE - 执行
redis-cli SHUTDOWN SAVE优雅停机(确保AOF/RDB落盘) - 重启后立刻验证
CONFIG GET两项参数
最容易被忽略的一点:主从架构下,从节点也要单独配置,因为CONFIG REWRITE不跨实例。从节点若没设maxmemory,可能比主节点更早OOM。


















