首页/数据/数据库速查/HSETNX 字段不存在才设置
Redis 命令96 条

HSETNX 字段不存在才设置

单字段版的「不存在才写」:返回 1 表示设置成功,0 表示字段已存在;不会覆盖已有值,原子单命令。

数据库速查数据更新于 2026-10-13

字段不存在才写入

HSETNX 是单字段版的「不存在才写」:字段不存在时写入并返回 1,已存在则返回 0 且不改动原值。它是单条命令,天然原子,适合初始化默认值而不覆盖用户已有设置的场景。

基本信息

适用Redis 2.0 及以上 Hash 命令
作用范围单个字段,不是整个键
原子性单命令原子,无需额外加锁
返回值1 表示写入成功,0 表示字段已存在未改动

示例

示例
HSETNX task:88 status pending      # 1:字段不存在,写入成功
HSETNX task:88 status running      # 0:已存在,拒绝覆盖
HGET task:88 status                # pending:原值保持不变
HSETNX config:site theme light     # 初始化默认配置,不覆盖已设置项
HGETALL config:site                # 查看当前全部字段
HSTRLEN config:site theme          # 字段值的字节长度

返回值与语义

返回值含义业务处理
1字段原先不存在,已写入按新值初始化处理
0字段已存在,未改动属于正常语义,不要当异常重试
键不存在时相当于新建 Hash 并写入返回 1
多字段初始化逐字段调用或改用 Lua注意多次调用之间的并发窗口

典型使用场景

  • 初始化默认配置,保留用户已设置的项
  • 任务状态幂等初始化:只在首次设置状态
  • 灰度标记写入:不覆盖已有的分组标记
  • 补齐缺失字段,避免影响已存在的数据
  • 配合 HGETALL 做配置合并前的准备动作
需要整键级别的「不存在才写」时用 SET 的 NX 选项;需要多字段一起判断时,用 Lua 把判断与写入合成一次原子操作。
不要用 HSETNX 实现跨进程互斥:不同进程写不同字段都可能返回 1,互斥必须用 SET NX 加过期时间或专门的锁方案。

与相关命令的分工

  • 整键级不存在才写用 SET 的 NX 选项,而不是 HSETNX
  • 字段存在也要覆盖时用 HSET,语义更直接
  • 多字段一起判断再写入时用 Lua 脚本保证原子性
  • 判断字段是否存在用 HEXISTS,写入用 HSETNX,两者职责不同

幂等初始化的写法

  • 用 HSETNX 逐字段初始化默认值,用户已设置的项不会被覆盖
  • 需要整批默认值时,可在应用层先读一次再决定写哪些字段
  • 初始化脚本重复执行也不会产生副作用,适合放在部署流程里

易错点

  • 用 HSETNX 做并发互斥:多个进程仍可能各自成功,互斥语义不成立
  • 把返回 0 当异常重试:0 是「已存在」的正常语义,重试反而浪费资源
  • 多字段初始化逐条执行:各条之间存在并发窗口,需要原子时改用 Lua
  • 以为 HSETNX 会覆盖空字符串字段:字段存在即返回 0,空值同样不会被改写

数据来源与参考

  • Redis 官方文档: HSETNX

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌