Redis原理:setnx

setnx 命令的使用方式如下:

复制代码
SETNX key value

Set key to hold string value if key does not exist. In that case, it is equal to SET. When key already holds a value, no operation is performed. SETNX is short for "SET if N ot eXists".

中文:如果key不存在,则创建key,并设置相应的值

源码

复制代码
void setnxCommand(client *c) {
    c->argv[2] = tryObjectEncoding(c->argv[2]);
    // 调用通用的方法,并传递OBJ_SET_NX标号
    setGenericCommand(c,OBJ_SET_NX,c->argv[1],c->argv[2],NULL,0,shared.cone,shared.czero);
}

setGenericCommand 是一个通用方法,比较多的命令也都是通过该方法来处理的

复制代码
void setGenericCommand(client *c, int flags, robj *key, robj *val, robj *expire, int unit, robj *ok_reply, robj *abort_reply) {
    long long milliseconds = 0; /* initialized to avoid any harmness warning */
    int found = 0;
    int setkey_flags = 0;

    if (expire && getExpireMillisecondsOrReply(c, expire, flags, unit, &milliseconds) != C_OK) {
        return;
    }

    if (flags & OBJ_SET_GET) {
        if (getGenericCommand(c) == C_ERR) return;
    }
    // 按key进行查询
    found = (lookupKeyWrite(c->db,key) != NULL);
    // 如果是SetNx命令,并且找到,则直接返回
    if ((flags & OBJ_SET_NX && found) ||
        (flags & OBJ_SET_XX && !found))
    {
        if (!(flags & OBJ_SET_GET)) {
            addReply(c, abort_reply ? abort_reply : shared.null[c->resp]);
        }
        return;
    }

    setkey_flags |= (flags & OBJ_KEEPTTL) ? SETKEY_KEEPTTL : 0;
    setkey_flags |= found ? SETKEY_ALREADY_EXIST : SETKEY_DOESNT_EXIST;

    setKey(c,c->db,key,val,setkey_flags);
    server.dirty++;
    notifyKeyspaceEvent(NOTIFY_STRING,"set",key,c->db->id);

    .. 省略部分代码

    if (!(flags & OBJ_SET_GET)) {
        addReply(c, ok_reply ? ok_reply : shared.ok);
    }

    .. 省略部分代码
}

这里只看关于setnx相关的代码,其实也很简单,从数据库获取key对应的值,如果存在,则直接返回。

如果不存在,则通过setkey方法进行创建key。

在官方文档的setnx命令的开始,就有如下的说明

As of Redis version 2.6.12, this command is regarded as deprecated.

It can be replaced by SET with the NX argument when migrating or writing new code.

从2.6.12 开始,setnx 已经被标识为deprecated, 需要通过set 命令中,通过指定nx参数来替代。

复制代码
SET key value [NX | XX] [GET] [EX seconds | PX milliseconds |
  EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]

set 命令将在下一节完整分析下。

相关推荐
雪域迷影6 分钟前
Windows11上安装Redis服务和Redis可视化客户端
windows·redis
青云交13 分钟前
Java 大视界 -- 基于 Java+Redis Cluster 构建分布式缓存系统:实战与一致性保障(444)
java·redis·缓存·缓存穿透·分布式缓存·一致性保障·java+redis clus
三不原则32 分钟前
故障案例:模型推理响应慢,排查 Redis 缓存集群问题
数据库·redis·缓存
小北方城市网13 小时前
分布式锁实战指南:从选型到落地,避开 90% 的坑
java·数据库·redis·分布式·python·缓存
ohoy14 小时前
RedisTemplate 使用之Zset
java·开发语言·redis
冰冰菜的扣jio17 小时前
Redis缓存中三大问题——穿透、击穿、雪崩
java·redis·缓存
阿里巴巴P8资深技术专家18 小时前
基于 Spring AI 和 Redis 向量库的智能对话系统实践
人工智能·redis·spring
oMcLin18 小时前
如何在 AlmaLinux 9 上配置并优化 Redis 集群,支持高并发的实时数据缓存与快速查询?
数据库·redis·缓存
洛阳纸贵19 小时前
Redis
数据库·redis·缓存
挺6的还20 小时前
13.持久化
redis