*Redis MSETNX 命令

MSETNX 原子性地设置多个 key-value 对,但仅当所有指定的键都不存在时才执行设置。


*语法

MSETNX key value [key value ...]

*参数说明

参数 类型 必填 说明
key String 键名
value String / Bytes 键值

*返回值

  • 1:所有键都不存在,设置成功
  • 0:至少有一个键已存在,未执行任何设置

*时间复杂度

O(N),N 为设置的 key-value 对数量


*示例

*全部不存在时设置成功

> MSETNX key1 "value1" key2 "value2"
(integer) 1
> GET key1
"value1"
> GET key2
"value2"

*部分存在时设置失败

> SET key1 "existing"
OK
> MSETNX key1 "new1" key2 "new2"
(integer) 0
> GET key2
(nil)

*批量初始化配置

> MSETNX config:db "mysql" config:cache "redis" config:port "8080"
(integer) 1

*常见错误

错误 原因 解决
ERR wrong number of arguments 参数数量不成对 确保每个 key 都有对应的 value

*最佳实践

  • 适合初始化一组关联数据,确保要么全部创建要么全不创建
  • 原子性保证,避免部分 key 设置成功导致的数据不一致
  • 可用于分布式锁的批量加锁场景(但 Redis 分布式锁推荐 RedLock 或 SET NX EX)
  • 键数量建议一次不超过 1000 个
  • 注意:MSETNX 不设置过期时间,需要手动 EXPIRE

*FAQ

Q1: MSETNX 和 MSET 有什么区别? A: MSETNX 是条件设置(全部不存在时才设置),MSET 是无条件覆盖。

Q2: 和多次 SETNX 有什么区别? A: MSETNX 是原子操作,而多次 SETNX 之间可能有其他客户端插入设置。

Q3: 返回 0 时怎么知道哪个 key 已存在? A: MSETNX 不返回具体信息,需用 EXISTS 逐一检查或 MGET 判断。

Q4: 可以设置过期时间吗? A: MSETNX 本身不支持,设置成功后需额外调用 EXPIREPEXPIRE

Q5: 值为空字符串时算存在吗? A: 空字符串 "" 是存在的值,MSETNX 会判断为已存在。