Redis内存淘汰规则设置教程
什么时候需要设置内存淘汰规则
Redis 默认没有开启最大内存限制,一旦数据量超过物理内存,系统就可能触发 OOM(内存溢出)导致服务崩溃。
生产环境里,多数云 Redis 实例默认会设置 maxmemory,但淘汰规则(maxmemory-policy)却常常保持默认 noeviction——意味着内存满了之后,写入操作直接返回错误。
如果你遇到过“OOM command denied”报错,那多半就是因为没有调整淘汰规则。
本文面向刚接触 Redis 的新手,不涉及底层源码,只讲你真正需要执行的步骤和原理。
操作前确认两件事
- Redis 版本:不同版本对淘汰策略的支持略有差异,建议使用 4.0 及以上。可以通过
redis-server --version检查。 - 当前内存使用量:登录 Redis 后执行
info memory,看used_memory_human字段,了解当前占用。如果还没有设置maxmemory,可以先通过config get maxmemory查看,默认是0(无限制)。
核心步骤:修改内存淘汰规则
方法一:运行时修改(临时生效,重启丢失)
# 进入 Redis 命令行
redis-cli
# 设置最大内存为 512MB(单位:字节,512*1024*1024=536870912)
CONFIG SET maxmemory 536870912
# 设置淘汰策略为 allkeys-lru(常用策略之一)
CONFIG SET maxmemory-policy allkeys-lru
# 验证是否生效
CONFIG GET maxmemory
CONFIG GET maxmemory-policy
allkeys-lru 是最常用的策略:当内存超过限制时,从所有 key 中淘汰最近最少使用的 key。
适合大部分缓存场景。
方法二:修改配置文件(永久生效)
找到 Redis 配置文件(通常为 /etc/redis/redis.conf 或 /etc/redis/6379.conf),编辑以下两个参数:
sudo vim /etc/redis/redis.conf
找到或添加:
# 设置最大内存,单位字节,例如 512MB
maxmemory 536870912
# 设置淘汰策略
maxmemory-policy allkeys-lru
保存后重启 Redis:
sudo systemctl restart redis # 或 sudo service redis-server restart
重启后记得再次执行 config get maxmemory-policy 确认生效。
常见淘汰策略说明及选型建议
| 策略 | 行为 | 适用场景 |
|------|------|----------|
| noeviction | 不淘汰,写入返回 OOM 错误 | 默认,不推荐生产用 |
| allkeys-lru | 从所有 key 中淘汰最近最少使用 | 缓存场景首选 |
| volatile-lru | 仅淘汰设置了过期时间的 key 中最近最少使用 | 混合缓存与持久数据 |
| allkeys-lfu | 淘汰使用频率最低的 key(Redis 4.0+) | 热点明显、频率稳定的场景 |
| volatile-ttl | 淘汰即将过期的 key(优先删除 ttl 最小的) | 需要优先淘汰短时效数据 |
| volatile-random | 在有过期时间的 key 中随机淘汰 | 特殊场景较少用 |
新手建议直接使用 allkeys-lru,简单有效。
如果存储了不能丢失的持久数据,再用 volatile-lru,并确保那些数据不要设置过期时间。
避坑指南
- 设置
maxmemory要留余量:数值不要接近物理内存上限,推荐设置为实际可用内存的 70%~80%。如果 Redis 和操作系统共用一个机器,还要为系统和其他进程预留内存。 - 修改
maxmemory-policy后立即验证:执行info stats查看evicted_keys计数,如果淘汰策略生效,evicted_keys会逐步增加。如果长时间为 0 但内存已满,说明策略可能无效或maxmemory未正确配置。 - 主从复制环境注意:从库默认不执行淘汰,主库淘汰后同步给从库。如果在从库直接执行写入(不推荐),需要单独配置
maxmemory。 FLUSHALL和FLUSHDB不影响淘汰计数:清空后淘汰计数不会重置,但所有 key 被清除,可能会产生误导。
效果验证
连接 Redis 后执行以下命令确认:
redis-cli
INFO memory | grep -E "used_memory_human|maxmemory|evicted_keys"
理想输出类似:
used_memory_human:480.56M
maxmemory:536870912
maxmemory_human:512.00M
evicted_keys:0
如果 evicted_keys 大于 0,说明淘汰已经在工作。
你也可以手动插入大量数据测试:
redis-cli DEBUG POPULATE 1000000 # 插入100万个测试key(危险!生产环境禁用)
观察 INFO memory 中的 evicted_keys 是否增加。注意:测试完立即删除测试 key:redis-cli FLUSHDB。
如果你在操作中遇到 (error) command not allowed when used memory > 'maxmemory' 提示,说明当前淘汰策略为 noeviction,请优先修改为 allkeys-lru 再继续。
修改后如果还有报错,检查 maxmemory 设置是否大于当前 used_memory——理论上应该开启淘汰后腾出空间,但如果 maxmemory 设得太小,也可能持续淘汰导致写入抖动,此时适当调大上限即可。