☰
Redis命令:LREM
2026/10/19 2:07:56 网站建设 项目流程

Redis LREM 命令详细教程

LREM移除列表中与指定元素相等的前 count 个元素,是按值删除列表元素的基础命令。count 同时决定删除数量与扫描方向:可以从表头向表尾删、从表尾向表头删,也可以一次性删完全部匹配。它从 Redis 1.0.0 起提供,常用于清理队列中的无效任务或按值维护列表内容。

资料合集:https://pan.quark.cn/s/10e98d308913、https://pan.quark.cn/s/f56bc69c5338

一、概览与语法

LREM key count element
项目说明
数据类型List
支持版本Redis 1.0.0 起
key目标列表 Key
count移除数量与方向:大于 0 从表头向表尾移除 count 个;小于 0 从表尾向表头移除 count 的绝对值个;等于 0 移除全部匹配元素
element要移除的目标值,按字节精确匹配
返回值整数:本次被移除的元素个数
时间复杂度O(N+M),N 为列表长度,M 为被移除的元素数
ACL@write、@list、@slow
命令标记write

官方说明:从存储于 key 的列表中移除前 count 个与 element 相等的元素。count 大于 0 时从表头向表尾移除;count 小于 0 时从表尾向表头移除;count 等于 0 时移除所有匹配元素。$TRAE_REF

二、基础示例

以下命令在测试实例的 redis-cli 中执行。文中结果是预期说明,未实际连接 Redis 运行。示例沿用官方文档的数据与结果。

DEL tutorial:{lrem}:mylist RPUSH tutorial:{lrem}:mylist "hello" RPUSH tutorial:{lrem}:mylist "hello" RPUSH tutorial:{lrem}:mylist "foo" RPUSH tutorial:{lrem}:mylist "hello" LREM tutorial:{lrem}:mylist -2 "hello" LRANGE tutorial:{lrem}:mylist 0 -1

预期结果:列表初始为"hello"、"hello"、"foo"、"hello"共 4 个元素;LREM的 count 为 -2,表示从表尾向表头移除 2 个"hello",返回2;最后LRANGE返回"hello"、"foo",被移除的是末尾两个 hello,表头 hello 与中间的 foo 保留。

三、count 参数的三种语义

count 的正负与零决定删除方向和数量,用同一个列表分别验证:

DEL tutorial:{lrem}:ex RPUSH tutorial:{lrem}:ex a b a a LREM tutorial:{lrem}:ex 2 a LRANGE tutorial:{lrem}:ex 0 -1 DEL tutorial:{lrem}:ex RPUSH tutorial:{lrem}:ex a b a a LREM tutorial:{lrem}:ex -2 a LRANGE tutorial:{lrem}:ex 0 -1 DEL tutorial:{lrem}:ex RPUSH tutorial:{lrem}:ex a b a a LREM tutorial:{lrem}:ex 0 a EXISTS tutorial:{lrem}:ex

预期结果:列表初始为a、b、a、a。count 为 2 时从表头扫描,移除索引 0 和 2 的两个 a,返回2,剩余b、a;count 为 -2 时从表尾扫描,移除索引 3 和 2 的两个 a,返回2,剩余a、b;count 为 0 时移除全部 3 个 a,返回3,列表被清空且 Key 随之删除,EXISTS返回0。

四、返回值与空结果

LREM返回整数:被移除的元素个数。返回 0 有两种不可区分的情形——Key 不存在,或元素在列表中没有出现;两种情况都不报错。

情形返回
移除了 N 个匹配元素N
Key 不存在0
元素在列表中未出现0

如果业务需要区分“列表不存在”与“没匹配到元素”,应额外执行 EXISTS 或 TYPE 判断,不能只看 LREM 的返回值。

EXISTS tutorial:{lrem}:ex LREM tutorial:{lrem}:ex 1 a LREM tutorial:{lrem}:mylist 5 no-such

预期结果:上一节 count 为 0 的示例已把 ex 清空并删除 Key,EXISTS返回0;对不存在的 Key 执行LREM返回0;对存在的 mylist 移除未出现的元素同样返回0,三种结果无法从返回值区分。

五、精确匹配语义

  • 字节级比较:LREM按字节内容逐一比较元素,"A"与"a"是不同的值。
  • 不支持通配符:element 是普通字符串,"a*"只匹配字面的a*,不会匹配abc。
  • 空字符串可匹配:element 为空字符串是合法的,可以移除值为空串的元素。
RPUSH tutorial:{lrem}:ex "a" "A" "a*" LREM tutorial:{lrem}:ex 0 a LRANGE tutorial:{lrem}:ex 0 -1

预期结果:LREM返回1,只移除了小写的a;LRANGE返回"A"、"a*",大写 A 与带星号的 a* 均未被误删。

六、边界情况与错误处理

场景行为
Key 不存在返回 0,不报错
元素在列表中不存在返回 0,不报错
Key 类型不是 List报 WRONGTYPE
count 缺失或不是整数报语法错误或参数类型错误
element 为空字符串允许,按空串匹配
count 为 0移除全部匹配元素
SET tutorial:{lrem}:str text LREM tutorial:{lrem}:str 0 a

预期结果:对 String 类型执行报 WRONGTYPE,类型检查先于匹配扫描。

七、与相近命令的区别

命令定位方式是否修改列表说明
LREM按值匹配删除是(变短)按值删除前 count 个匹配元素
LPOS按值查找返回索引否只定位不删除,常与 LREM/LSET 组合
LTRIM按索引区间保留是(变短)区间语义同 LRANGE,与值无关
LPOP / RPOP按位置弹出是(变短)只删表头或表尾一个元素,不看值
DEL / UNLINK删除整个 Key是连 Key 带数据整体删除

选择思路:知道值用LREM,知道位置用LPOP/RPOP或LTRIM,只想查找用LPOS,整键放弃用DEL/UNLINK。

八、客户端示例

前提为已安装 redis-py 并准备好本地测试实例。redis-py 4.0 及以上版本的签名为lrem(name, count, value),旧版为lrem(name, value, num),升级时注意参数顺序。返回值为 int,表示移除个数。

importredis r=redis.Redis(host="localhost",port=6379,decode_responses=True)key="tutorial:{lrem}:py"try:r.delete(key)r.rpush(key,"a","b","a","a")print(r.lrem(key,2,"a"))# 2,从表头移除两个 aprint(r.lrange(key,0,-1))# ['b', 'a']print(r.lrem(key,0,"a"))# 1,移除剩余的全部 a,Key 随之删除print(r.lrem(key,1,"a"))# 0,Key 已不存在print(r.lrem("no-such",1,"a"))# 0,Key 不存在也不报错finally:r.delete(key)r.close()

Java(Jedis)示例,lrem返回long:

try(Jedisjedis=newJedis("localhost",6379)){Stringkey="tutorial:{lrem}:java";jedis.del(key);jedis.rpush(key,"a","b","a","a");System.out.println(jedis.lrem(key,-2,"a"));// 2,从表尾移除两个 aSystem.out.println(jedis.lrange(key,0,-1));// [a, b]System.out.println(jedis.lrem(key,0,"a"));// 1,删除最后一个 ajedis.del(key);}

九、原子性与性能

复杂度:O(N+M),N 为列表长度,M 为被移除的元素数。即使只删 1 个元素,最坏也要扫过整个列表定位它,因此LREM在大列表上属于潜在慢命令。

慢命令风险:对十万级以上元素的列表执行LREM key 0 x会完整扫描并可能大规模改写节点,阻塞事件循环。高频按值删除的场景应考虑改用 Hash、Set 或有序集合。

原子性:单命令原子,并发客户端无需加锁;在 MULTI/EXEC 与 Lua 脚本中可将多次 LREM 与其他命令组合成整体事务。

读改写组合非原子:先 LPOS 定位再 LREM 的两步操作之间可能被其他客户端插入,需要严格一致时用 WATCH 或 Lua 脚本包裹。

十、典型业务场景

队列清理:延迟队列中任务已失败或被取消,用LREM key 1 task-id按值移除该任务。

按值去重:列表被写入方重复投递后,用LREM key 0 value清掉某值的全部副本。

白名单维护:以 List 存放 IP 或用户白名单,退订时LREM key 1 user-id摘除。

先定位再删除:先用LPOS key element确认值的位置与份数,再决定 count 用 1 还是 0,避免误删。

十一、练习、排错与总结

练习:新建tutorial:{lrem}:ex,用 RPUSH 写入x y x z x;执行LREM ex 1 x确认返回1且剩余y x z x(只删表头的 x);再执行LREM ex -2 x返回2且剩余y z;重建列表后执行LREM ex 0 x返回3且EXISTS为0;对不存在的 Key 执行LREM返回0不报错;对 String Key 执行报 WRONGTYPE。

排错要点:返回 0 时先区分 Key 不存在与值未出现,用 EXISTS/TYPE 进一步判断;删多了通常是 count 误写成 0 或弄反了正负方向;没删干净检查值是否大小写或前后空格不一致;报 WRONGTYPE 时用 TYPE 检查类型;慢日志出现 LREM 时评估列表长度并考虑换数据结构。清理使用DEL tutorial:{lrem}:mylist tutorial:{lrem}:ex tutorial:{lrem}:str tutorial:{lrem}:py tutorial:{lrem}:java。速记:1.0 起支持、count 正头负尾零全部、返回被移除个数、返回 0 表示没删到(Key 不存在或未匹配,二者不可区分)、按字节精确匹配区分大小写、O(N+M) 大列表是慢命令、单命令原子、按值删除直接用 LREM 而不是先 LRANGE 再逐个删。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询