ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Redis命令:RPUSHX

Redis命令:RPUSHX

Redis RPUSHX 命令详细教程

RPUSHX将一个或多个元素追加到列表的表尾(右侧),与 RPUSH 的唯一区别是:只有当 Key 已存在且持有列表时才执行推入,Key 不存在时不创建、不报错,静默返回0。它从 Redis 2.2.0 起提供,4.0.0 起支持一次推入多个元素,适合"只更新、不新建"的保护性写入场景。

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

一、概览与语法

RPUSHX key element [element ...]
项目说明
数据类型List
支持版本Redis 2.2.0 起;4.0.0 起接受多个 element
key目标列表 Key,必须已存在
element一个或多个要追加的元素,按书写顺序依次追加到表尾
返回值推入后的列表长度;Key 不存在时返回 0
时间复杂度每个元素 O(1),一次推 N 个为 O(N)
ACL@write、@list、@fast
命令标记write、fast、denyoom

官方说明:当 key 已存在且持有列表时,RPUSHX 将所有指定值插入到存储于 key 的列表尾部;与 RPUSH 相反,当 key 尚不存在时不执行任何操作。$TRAE_REF

二、基础示例

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

DEL tutorial:{rpushx}:mylist tutorial:{rpushx}:myotherlist RPUSH tutorial:{rpushx}:mylist "World" RPUSHX tutorial:{rpushx}:mylist "Hello" RPUSHX tutorial:{rpushx}:myotherlist "Hello" LRANGE tutorial:{rpushx}:mylist 0 -1 EXISTS tutorial:{rpushx}:myotherlist

预期结果:RPUSH 返回1;对已存在的 mylist 追加返回2;对不存在的 myotherlist 追加返回0;LRANGE 返回"World"、"Hello"(参数顺序即列表顺序);EXISTS 返回0,确认 myotherlist 未被创建。

三、与 RPUSH 的核心差异

对比项RPUSHRPUSHX
Key 存在且为列表追加并返回新长度追加并返回新长度
Key 不存在先创建空列表再追加不创建,返回 0
副作用可能凭空产生新 Key无,绝不新建 Key
支持多元素2.4.0 起4.0.0 起

这个差异决定了两者的适用面:RPUSH 适合初始化与常规写入;RPUSHX 把"判断存在"和"追加"合并成一次原子操作,避免"先 EXISTS 检查再 RPUSH"这种两步流程在并发下产生的竞态。

四、多元素推入顺序

与 RPUSH 一致,多个元素按参数顺序依次追加到表尾,参数的书写顺序即最终列表顺序:

DEL tutorial:{rpushx}:order RPUSH tutorial:{rpushx}:order seed RPUSHX tutorial:{rpushx}:order a b c LRANGE tutorial:{rpushx}:order 0 -1

预期结果:RPUSHX 返回4;LRANGE 返回"seed"、"a"、"b"、"c"。版本注意:Redis 4.0 之前的 RPUSHX 每次只接受一个元素。

五、Key 不存在与类型错误

RPUSHX 返回0只有一种正常情形:Key 当前不存在(含刚被弹出最后一个元素而删除的情况)。列表类型不会以"空列表"形式存在,元素弹完 Key 即被删除。

场景行为
Key 不存在不创建,返回 0
Key 是其他类型报 WRONGTYPE
Key 已存在且为列表追加,返回新长度
Key 设置过 TTL追加不清除过期时间,到期仍会被删除
SET tutorial:{rpushx}:str text RPUSHX tutorial:{rpushx}:str x

预期结果:对 String 类型执行报 WRONGTYPE,类型检查先于任何写入。

六、与相近命令的区别

命令推入位置Key 不存在时支持多元素
RPUSHX表尾(右侧)不创建,返回 04.0.0 起
RPUSH表尾(右侧)创建列表后推入2.4.0 起
LPUSHX表头(左侧)不创建,返回 04.0.0 起
LPUSH表头(左侧)创建列表后推入2.4.0 起
LINSERT指定 pivot 前后不创建,返回 0不支持

四个命令的分工很清晰:普通命令负责"有则推、无则建",X 命令负责"有则推、无则放弃"。RPUSHX 与 LPUSHX 的区别仅在推入端:前者追加到表尾,后者插到表头。

七、边界情况与错误处理

场景行为
未提供任何 element参数数量不足,报语法错误
element 为空字符串允许,正常推入
Key 不存在返回 0,静默成功
Key 类型不是 List报 WRONGTYPE
返回值语义0 表示未推入(Key 不存在),正数表示推入后的长度
RPUSHX tutorial:{rpushx}:err

预期结果:缺少元素参数,报ERR wrong number of arguments for 'rpushx' command。

业务代码需要注意:RPUSHX 返回 0 不是错误,但通常意味着"列表尚未初始化",调用方应据此决定是否先执行初始化,而不是把它当成失败重试。

八、客户端示例

前提为已安装 redis-py 并准备好本地测试实例。redis-py 的rpushx(name, *values)返回推入后的长度,Key 不存在时返回 0。

importredis r=redis.Redis(host="localhost",port=6379,decode_responses=True)key="tutorial:{rpushx}:py"try:r.delete(key)print(r.rpushx(key,"a","b","c"))# 0,Key 不存在不创建r.rpush(key,"seed")print(r.rpushx(key,"a","b","c"))# 4print(r.lrange(key,0,-1))# ['seed', 'a', 'b', 'c']finally:r.delete(key)r.close()

Java(Jedis)示例,rpushx同样支持可变参数:

try(Jedisjedis=newJedis("localhost",6379)){Stringkey="tutorial:{rpushx}:java";jedis.del(key);System.out.println(jedis.rpushx(key,"a"));// 0,Key 不存在不创建jedis.rpush(key,"seed");System.out.println(jedis.rpushx(key,"a","b","c"));// 4System.out.println(jedis.lrange(key,0,-1));// [seed, a, b, c]jedis.del(key);}

九、原子性与使用注意事项

检查与写入合一:EXISTS key加RPUSH key x是两步流程,中间可能被其他客户端删除 Key 或改变类型;RPUSHX 把"必须已存在"作为前置条件在服务端一次性校验,是天然原子的。

TTL 不受影响:对已设置过期时间的 Key 执行 RPUSHX 不会清除 TTL。若业务期望"写入后重新计时",需要显式重设 EXPIRE。

Pipeline 与事务:RPUSHX 可正常用于管道与 MULTI/EXEC,返回值语义不变;批量追加用管道减少网络往返。

性能:每个元素 O(1),只操作表尾,与列表长度无关。

十、典型业务场景

保护性追加:时序日志、审计流水、事件流等由专门的初始化逻辑(写入元数据、设置 TTL)创建 Key 后,后续写入全部走 RPUSHX,防止下游异常调用凭空造出没有 TTL、没有元数据的孤儿 Key。

会话期流水:用户会话存在才继续记录操作流水,会话过期后自然停止追加,无需额外判断。

并发初始化保护:多个服务实例同时写同一个列表时,用 RPUSHX 保证"谁负责创建、谁才能写入"的语义清晰。

追加已有集合的明细:主记录存在才追加其明细项,避免产生孤立明细。

十一、练习、排错与总结

练习:新建tutorial:{rpushx}:ex1与tutorial:{rpushx}:ex2;对不存在的 ex1 执行RPUSHX ex1 a,确认返回0且 EXISTS 为0;执行RPUSH ex1 seed后执行RPUSHX ex1 b c,确认返回3且 LRANGE 得到seed,b,c;用 SET 把 ex1 改成 String 后再 RPUSHX,确认报 WRONGTYPE;最后对 ex2 重复验证 Key 不存在时的静默行为。

排错要点:RPUSHX 返回 0 时先怀疑 Key 未初始化,用 EXISTS、TYPE 确认;本想初始化列表时不要误用 RPUSHX,改用 RPUSH;报 WRONGTYPE 时检查 Key 是否被 String 等类型占用;老版本(4.0 前)报语法错误时检查是否使用了多元素写法;追加顺序与预期不符时确认元素是否被追加到表尾(RPUSHX 参数顺序即列表顺序)。清理使用DEL tutorial:{rpushx}:mylist tutorial:{rpushx}:myotherlist tutorial:{rpushx}:order tutorial:{rpushx}:str tutorial:{rpushx}:py tutorial:{rpushx}:java tutorial:{rpushx}:ex1 tutorial:{rpushx}:ex2。速记:2.2 起支持、4.0 起可推多个、只在 Key 已存在时追加到表尾、Key 不存在返回 0 且不创建、返回值为推入后的长度、不清除已有 TTL、与 RPUSH 的区别就在"是否创建"、X 系列命令都是"有则推无则弃"。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进