bigywater.tech
Redis · 25

maxmemory 限制

设maxmemory=3MB配合noeviction策略,验证写满之后的OOM报错和读操作依然可用,再对照allkeys-lru策略下同样超量写入全部成功。

714个key
noeviction下成功写入的极限数量
读不受影响
内存超限后只拒绝写不拒绝读
policy决定生死
同样超限,noeviction报错而allkeys-lru全部成功

做的事:把内存上限设得很紧,看写操作会怎样

noeviction策略下,maxmemory是一道硬墙。

操作CONFIG SET maxmemory-policy noeviction CONFIG SET maxmemory 3mb 循环SET,每个value 2000字节

验证:noeviction下,写满之后直接报错

第几个key开始被拒绝。

结果写入失败: command not allowed when used memory > 'maxmemory'. 成功写入了 714 个key才触发OOM used_memory: 3144560 maxmemory: 3145728

验证了noeviction策略下maxmemory是一条硬性红线:内存用量一旦超过这条线,所有会增加内存占用的写命令都会被直接拒绝,报出一个明确的OOM风格错误,不会尝试腾挪任何数据。

验证:内存写满之后,读操作还能用

被拒绝的只是"会让内存继续增长"的写操作。

结果GET k_0 → 成功返回了完整的2000字节值

确认了:maxmemory的限制只针对写操作,已经存进去的数据在内存超限之后依然可以正常读取——noeviction的语义是"不许再往里塞新数据,但已有数据完全不受影响",跟"内存耗尽系统崩溃"完全不是一回事。

验证:换成allkeys-lru,同样超量写入全部成功

同样的maxmemory,同样超量的写入,唯一变量是策略。

结果全部500次写入都成功,没有报错(触发了淘汰而不是拒绝)
这就是maxmemory的完整图景:maxmemory 本身只是划定了一条"内存该在什么时候开始有动作"的线,真正决定"超过这条线之后怎么办"的,是 maxmemory-policy——noeviction 选择"宁可让新写入失败,也不主动删任何数据",其它带淘汰算法的策略则选择"主动腾地方,让写入继续成功,代价是要牺牲掉一些旧数据"。没有配置淘汰策略的Redis实例默认就是noeviction,这也是为什么很多线上事故的表现是"Redis突然写不进去了但读还正常"——排查时第一反应应该是查maxmemory和maxmemory-policy,而不是以为服务挂了。

分步演示:写满内存后发生了什么

每一步都是本文上面用redis-cli和redis-py跑出来的原始结果。

maxmemory划线,maxmemory-policy决定线内怎么办
这一步新验证的结果

    本文用到的工具

    • 本机 Redis 8.10.1 单节点,maxmemory=3MB
    • noeviction vs allkeys-lru:对照两种策略对超量写入的处理方式
    京ICP备2026067502号-1京公网安备11010502063487号