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

Redis LSET 命令详细教程

LSET将列表指定索引位置的元素覆盖为新值,列表长度保持不变,是按位置改写元素的基础命令。索引规则与 LRANGE 一致,0 基且支持负索引从表尾倒数。它从 Redis 1.0.0 起提供,注意它不会自动创建 Key,索引越界与 Key 不存在都会直接报错。

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

一、概览与语法

LSET key index element
项目说明
数据类型List
支持版本Redis 1.0.0 起
key目标列表 Key
index目标位置索引,0 基,可为负数(-1 表示最后一个元素)
element覆盖后的新值
返回值简单字符串 OK
时间复杂度O(N),N 为列表长度;设置表头或表尾元素为 O(1)
ACL@write、@list、@slow
命令标记write、denyoom

官方说明:将列表 index 位置的元素设置为 element。索引超出范围或 Key 不存在时返回错误。$TRAE_REF

二、基础示例

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

DEL tutorial:{lset}:mylist RPUSH tutorial:{lset}:mylist "one" "two" "three" LSET tutorial:{lset}:mylist 0 "four" LRANGE tutorial:{lset}:mylist 0 -1

预期结果:LSET返回OK;LRANGE返回"four"、"two"、"three",索引 0 的 one 被覆盖为 four,列表长度仍为 3。

三、索引规则

LSET 与 LRANGE 使用同一套索引约定:

  • 0 基索引:表头元素是 0,不是 1。
  • 负索引:-1 是最后一个元素,-2 是倒数第二个,以此类推。
  • 长度不变:LSET 只做覆盖,不插入也不删除,执行前后 LLEN 相同。
  • 首尾最快:索引 0 与 -1 直接定位端点,复杂度 O(1);中间位置需要从表头或表尾走到目标。
LSET tutorial:{lset}:mylist -1 "six" LRANGE tutorial:{lset}:mylist 0 -1 LLEN tutorial:{lset}:mylist

预期结果:LSET返回OK;列表变为"four"、"two"、"six";LLEN返回3,长度未变。

四、越界与 Key 不存在

LSET有两类专属错误,需要单独留意:

  • 索引越界:对非空列表执行时,index 必须落在[0, LLEN-1]区间内或是有合法负索引,否则报ERR index out of range。
  • Key 不存在:LSET不会像 LPUSH 那样自动创建 Key,对不存在的 Key 执行报ERR no such key。
LSET tutorial:{lset}:nokey 0 x EXISTS tutorial:{lset}:nokey LSET tutorial:{lset}:mylist 5 x

预期结果:第一条报ERR no such key;EXISTS返回0,确认 LSET 没有创建 Key;第三条对长度 3 的列表设置索引 5,报ERR index out of range。示例中的 nokey 从未被成功创建,无需清理。

五、返回值说明

成功时LSET恒返回简单字符串OK,失败时直接报错,没有“部分成功”的中间态。由于成功与失败都是明确结果,客户端可以依据返回值可靠判断;但不能用 LSET 给不存在的 Key 建表,这是它与 LPUSH/RPUSH 的本质差异。

结果返回
覆盖成功OK
Key 不存在ERR no such key
索引越界ERR index out of range
Key 类型不是 ListWRONGTYPE
ERR no such key ERR index out of range WRONGTYPE Operation against a key holding the wrong kind of value

六、边界情况与错误处理

场景行为
Key 不存在报 ERR no such key,不创建 Key
索引越界(超出长度或非法负索引)报 ERR index out of range
Key 类型不是 List报 WRONGTYPE
element 为空字符串允许,正常覆盖
缺少 index 或 element报语法错误
空列表列表非空才存在,实际不会遇到;Key 不存在走 no such key
SET tutorial:{lset}:str text LSET tutorial:{lset}:str 0 a

预期结果:对 String 类型执行报 WRONGTYPE,类型检查先于索引定位。

七、与相近命令的区别

命令操作方式列表长度说明
LSET按索引覆盖不变只改写指定位置的值
LINSERT按值邻位插入加 1在锚点元素前后插入,不改锚点
LPOS按值查索引不变返回匹配元素的索引,常与 LSET 组合
LREM按值删除变短删除匹配元素
LPUSH / RPUSH两端追加加 1可对不存在的 Key 自动创建列表

“查找替换”组合:先LPOS key element拿到索引,再LSET key index newValue,即可按值精准覆盖,不影响其他元素。

八、客户端示例

前提为已安装 redis-py 并准备好本地测试实例。redis-py 的lset(name, index, value)成功返回 True,失败抛出 ResponseError。

importredis r=redis.Redis(host="localhost",port=6379,decode_responses=True)key="tutorial:{lset}:py"try:r.delete(key)r.rpush(key,"one","two","three")print(r.lset(key,0,"four"))# Trueprint(r.lrange(key,0,-1))# ['four', 'two', 'three']print(r.lset(key,-1,"six"))# True,负索引覆盖表尾print(r.lrange(key,0,-1))# ['four', 'two', 'six']try:r.lset(key,5,"x")# 索引越界exceptredis.exceptions.ResponseErrorase:print(e)# index out of rangefinally:r.delete(key)r.close()

Java(Jedis)示例,lset返回"OK",错误情形抛出 JedisDataException:

try(Jedisjedis=newJedis("localhost",6379)){Stringkey="tutorial:{lset}:java";jedis.del(key);jedis.rpush(key,"one","two","three");System.out.println(jedis.lset(key,1,"TWO"));// OKSystem.out.println(jedis.lrange(key,0,-1));// [one, TWO, three]try{jedis.lset("tutorial:{lset}:nokey",0,"x");}catch(redis.clients.jedis.exceptions.JedisDataExceptione){System.out.println(e.getMessage());// ERR no such key}jedis.del(key);}

九、原子性与并发安全

单命令原子:LSET本身原子执行,并发客户端同时改写同一索引时最后执行者获胜,不会出现半写状态。

读改写组合非原子:典型模式“LINDEX 读出旧值、业务判断、LSET 写回新值”由三步组成,整体不具备原子性,并发下可能覆盖他人刚写入的修改(丢失更新)。

解决方案:需要“读取-判断-写回”一致语义时,用 WATCH/MULTI/EXEC 乐观锁,或把整段逻辑放进 Lua 脚本执行。

性能:中间位置的定位是 O(N);大列表上高频改写中间元素有开销,若热点更新集中且顺序无业务意义,考虑改用 Hash 按字段更新。

十、典型业务场景

状态回写:任务列表中某个任务完成后,用LSET key idx new-status把对应元素替换为带新状态的值。

轮播与推荐位:以 List 维护坑位顺序,运营调整某个坑位内容时按索引覆盖。

按值精准替换:LPOS查索引 +LSET覆盖,实现“把元素 a 替换为 b”而不动其他元素。

修复脏数据:列表某位置的值写错时直接按索引改写,避免删了重插破坏原有顺序。

十一、练习、排错与总结

练习:新建tutorial:{lset}:ex,用 RPUSH 写入a b c;执行LSET ex 1 B返回OK且列表变为a B c;执行LSET ex -1 C返回OK且列表变为a B C,LLEN仍为3;执行LSET ex 3 x报ERR index out of range;对不存在的 Key 执行LSET报ERR no such key且EXISTS为0;对 String Key 执行报 WRONGTYPE。

排错要点:报 no such key 时确认是否误以为 LSET 会建 Key,应先 RPUSH/LPUSH 再改写;报 index out of range 时先用 LLEN 核对长度,注意负索引最小只到 -LLEN;值没变检查是否改错了索引(0 基);报 WRONGTYPE 时用 TYPE 检查类型;并发覆盖问题用 WATCH 或 Lua 包裹读改写流程。清理使用DEL tutorial:{lset}:mylist tutorial:{lset}:ex tutorial:{lset}:str tutorial:{lset}:py tutorial:{lset}:java(示例中的 nokey 从未被创建,无需清理)。速记:1.0 起支持、按索引覆盖长度不变、返回 OK、不创建 Key、Key 不存在与索引越界都报错、首尾 O(1) 中间 O(N)、与 LPOS 组合实现查找替换、读改写组合需自行保证原子性。

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

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

立即咨询