lua-time-limit 限制脚本执行最大毫秒数而非内存,设为0或过小仅触发script kill中断,无法阻止内存暴涨;脚本中redis.call的真实读写会直接影响volatile-lru/ttl等淘汰策略。

lua-time-limit 不是用来限制内存占用的
lua-time-limit 配置项控制的是 Lua 脚本执行的**最大毫秒数**,不是内存上限。把它设成 0 或很小的值(比如 5),只会让超时脚本被 SCRIPT KILL 中断,但不会阻止脚本本身分配大量内存——比如用 table.insert 循环生成百万级数组,或用 redis.call('GET', ...) 批量读取大 value,这些操作在超时前就可能把内存打爆。
真正影响内存淘汰的是脚本执行期间的数据访问模式
Lua 脚本执行时是单线程原子运行的,它调用的 redis.call 命令会真实读写数据,触发的 key 访问行为会直接影响淘汰策略判断:
- 如果脚本反复读写带 TTL 的 key(比如做计数+过期检查),可能让
volatile-lru或volatile-ttl策略更频繁地触发淘汰 - 如果脚本里
redis.call('SET', 'bigkey', string.rep('x', 10 写入超大 value,直接推高 <code>used_memory,更快触达maxmemory上限 - 脚本执行完才释放临时变量,所以长脚本 = 更久持有内存引用,GC 延迟更明显
防止 Lua 导致 OOM 的实际配置组合
光调 lua-time-limit 没用,得配合其他硬性约束:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 必须设置
maxmemory,例如maxmemory 2gb,否则 Redis 会吃光系统内存后被 OOM Killer 杀掉 - 搭配使用
maxmemory-policy allkeys-lru或allkeys-lfu,避免noeviction下写失败引发业务异常 - 通过 ACL 限制非可信用户执行
EVAL/EVALSHA,例如:ACL SETUSER appuser -EVAL -EVALSHA -SCRIPT - 若用脚本做聚合计算,提前在应用层控制输入规模(如限制
KEYS数量、ARGV总长度),别让脚本承担“防呆”责任
调试时怎么确认是 Lua 引起的内存压力
别只看 INFO memory,重点查这几项:
-
used_memory_peak_human:峰值内存,对比当前used_memory_human,差值大说明有大对象未释放(可能是脚本残留) -
mem_allocator和mem_fragmentation_ratio:碎片率 > 1.5 且used_memory_rss远高于used_memory,说明脚本分配/释放不均导致碎片 - 执行
SCRIPT EXISTS <sha></sha>或SCRIPT FLUSH后观察内存是否回落——如果回落明显,说明缓存的脚本体(尤其带大 table 初始化的)占了大量字典空间
真正难处理的从来不是超时,而是脚本里那些看似无害的 redis.call 调用,在高并发下把内存和淘汰策略一起拖进雪崩边缘。










