必须用 LPUSH + LTRIM 组合且 LTRIM 参数用负数索引,因 LPUSH 单独使用导致内存溢出,LPOP/RPOP 会误删最新数据,而 LTRIM key -N -1 可安全保留最新 N 条且自动边界裁剪,高并发下需 Lua 原子执行,并通过 LRANGE 验证结果。

必须用 LPUSH + LTRIM 组合,且 LTRIM 参数必须用负数索引,否则极易清空列表。
为什么不能只用 LPUSH 或 LPOP
单纯 LPUSH 会让 List 无限增长,内存持续上涨;而用 LPOP 或 RPOP 清理,会误删最新数据——因为 LPUSH 插入在头,RPOP 删除在尾(即最老的一条),和“保留最新 N 条”目标完全相反。List 是栈式结构,方向感错一点,逻辑就全反了。
LTRIM key -N -1 是唯一安全写法
负数索引天然适配“取最新”的语义:-1 永远指向最后一个(最新)元素,-N 表示倒数第 N 个。Redis 在执行时会自动做边界裁剪:即使当前 List 长度不足 N,LTRBIM key -100 -1 也不会报错或清空,而是保留全部现有元素。
- 想留最新 100 条?固定写
LTRBIM key -100 -1 - 千万别算正数起始位,比如
LTRBIM key 0 99—— 这要求你先LLEN再判断长度,中间有竞态,还容易因并发插入导致计算失效 - 更别写
LTRBIM key 50 149这类硬编码范围,List 长度一变就崩
高并发下必须用 Lua 脚本保障原子性
LPUSH 和 LTRBIM 是两条独立命令,中间存在微小时间窗口。多个客户端同时写入时,可能出现 A 写入、B 写入、A 执行 LTRBIM、B 执行 LTRBIM,结果某次插入被漏截,短暂超长。
用 Lua 把两步锁死成一个原子操作:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
eval "redis.call('LPUSH', KEYS[1], ARGV[1]); redis.call('LTRIM', KEYS[1], -100, -1); return 1" 1 mylist "new_item"
注意:Lua 中不能直接写 -100 这样的字面量负数索引(部分旧版 Redis 解析异常),稳妥起见可传参或拼接字符串。
调试时别只信返回值,要用 LRANGE 验证
LTRBIM 成功永远返回 OK,失败(如参数越界)也返回 OK——它不报错,只静默清空。所以每次调整后,务必手动执行:
LRANGE mylist 0 -1
看实际长度和内容是否符合预期。尤其上线前,在低峰期用真实数据压测一次 LPUSH+LTRBIM 流程,确认不会意外归零。
负数索引是唯一能绕过长度预判、规避清空风险的写法,也是所有稳定业务线的实际选择。其他方式要么不可靠,要么增加复杂度却不解决问题。

















