Redis的maxmemory需结合物理内存、部署角色及隐性开销综合设定:独占服务器可设为物理内存80%~90%并预留≥500MB系统内存;与Web共存时需大幅削减;纯缓存场景须同步调大复制积压和客户端缓冲区;单位必须用gb而非g,禁用maxmemory 0;淘汰策略须匹配数据访问模式,避免noeviction。

maxmemory设多少,得先看物理内存和部署角色
Redis的maxmemory不是拍脑袋定的数字,它必须和服务器总内存、Redis在系统中承担的角色强绑定。如果你的机器是16GB物理内存,Redis只是缓存服务(后端有DB兜底),且没有其他重量级进程共存,那maxmemory设到10–12GB是稳妥的;但要是这台机器还跑着Nginx、PHP-FPM、数据库客户端甚至监控Agent,那就得砍到6–8GB起步——别只盯着Redis自己。
常见错误现象:used_memory_human显示用了7.2GB,但ps aux看到redis进程RSS高达11GB,接着系统开始swap或OOMKiller介入。这不是Redis“吃多了”,而是你没把缓冲区、碎片、复制积压这些隐性开销算进去。
- 仅Redis单实例独占服务器:可设为物理内存的80%~90%,但必须预留至少500MB给系统(
maxmemory不能等于free -h里看到的可用内存) - Redis + Web服务共存(如8G内存小站):建议
maxmemory≤ 3GB,留足4GB以上给OS和应用 - 纯缓存场景(数据可丢):允许更高水位,但需同步调大
repl-backlog-size和client-output-buffer-limit,否则淘汰还没开始,缓冲区先爆了
为什么不能直接按“数据大小 × 2”粗略估算?
一个SET user:1001 "abc"逻辑上才几个字节,实际内存占用可能达120字节以上——robj头、SDS结构、dictEntry指针、jemalloc对齐填充全要算。更关键的是,Redis内存不是静态的:主从同步时repl-backlog默认1MB,AOF重写期间新写入命令会进aof_rewrite_buf,订阅客户端的输出缓冲可能瞬间涨到几十MB。这些都不计入used_memory,但都吃物理内存。
实操建议:
- 上线前用
redis-cli --memstat-stats扫一遍key分布,重点看hash/set/zset这类结构体密集型类型 - 执行
INFO memory,对比used_memory和used_memory_rss,若比值mem_fragmentation_ratio> 1.5,说明碎片严重,此时调高maxmemory只会加速OOM,应先做内存整理或升级到Redis 7.0+启用active-defrag - 监控必须覆盖
used_memory_peak_human,它反映历史最高水位,比当前值更有容量规划价值
单位写错会导致maxmemory失效,这些细节必须盯死
maxmemory 2g和maxmemory 2gb在Redis里含义不同:g被识别为千进制(1000³ = 1,000,000,000),而gb才是二进制(1024³ = 1,073,741,824)。差7.3%看似不多,但放到32GB机器上就是2.3GB偏差。更隐蔽的是maxmemory 0——这是默认值,等于不限制,生产环境绝不能留这个配置。
验证方式很简单:
- 改完
redis.conf后,执行CONFIG GET maxmemory确认返回值是期望的整数(如2147483648),不是字符串"2gb"或"0" - 临时设置用
CONFIG SET maxmemory 2gb没问题,但必须跟一句CONFIG REWRITE,否则重启就丢失 - 如果看到启动日志里有
WARNING: You specified a maxmemory value that is less than 1 MB,说明单位解析失败,立刻检查配置文件语法
淘汰策略不匹配,maxmemory再准也没用
maxmemory只是划了条线,真正决定“谁该被踢出去”的是maxmemory-policy。设了maxmemory 4gb却用noeviction策略,一超限就直接报OOM command not allowed when used memory > 'maxmemory',写请求全挂;而用allkeys-lru又可能把冷数据全清掉,热数据反而留不住。
选策略的关键不是背口诀,是看数据访问模式:
- 业务明确分热/冷数据(比如session + 配置缓存):用
volatile-lru,只淘汰带TTL的key,保底数据安全 - 全是短生命周期缓存(TTL统一设30分钟):
volatile-ttl比LRU更精准 - 无法加TTL的场景(如用户token无过期):只能选
allkeys-lfu,靠访问频次保热key - 任何情况下都不要用
noeviction上生产——它不是“安全模式”,是“拒绝服务模式”
真正容易被忽略的是:淘汰动作本身要消耗CPU和内存。当used_memory频繁贴近maxmemory阈值时,Redis会进入“淘汰抖动”状态,响应延迟毛刺明显。这时与其调高maxmemory,不如先查是不是有大key在反复写入、或者客户端缓冲区泄漏没清理。


















