*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 本身不支持,设置成功后需额外调用 EXPIRE 或 PEXPIRE。
Q5: 值为空字符串时算存在吗? A: 空字符串 "" 是存在的值,MSETNX 会判断为已存在。