Redis dig deep del

Time:2020-3-24

Command Brief

Usage:

DEL key [key ...]

Delete one or more given keys.

Keys that do not exist are ignored.

Return value:

Number of deleted keys.

Example:

redis> SET name huangz
OK

redis> DEL name
(integer) 1


#Delete a key that does not exist

redis> EXISTS phone
(integer) 0

Redis > del phone failed, no key was deleted
(integer) 0

Source code analysis

Command file:src/db.c

delandunlinkBe similar,unlinkAnother thread (in bio. C) will be started (conditionally) for space reclamation. andDELIt will block.

  • delGenericCommand
void delCommand(client *c) {
    delGenericCommand(c,0);
}


void unlinkCommand(client *c) {
    delGenericCommand(c,1);
}


.
.
.

//Del parameter ` lazy '= 0
void delGenericCommand(client *c, int lazy) {
    int numdel = 0, j;
    for (j = 1; j < c->argc; j++) {
        //Check whether it is expired. If the expired server. Lazyfree? Lazy? Expire = 1 is also an asynchronous deletion
        expireIfNeeded(c->db,c->argv[j]);
        //If lazy is 1 asynchronous delete
        int deleted  = lazy ? dbAsyncDelete(c->db,c->argv[j]) :
                              dbSyncDelete(c->db,c->argv[j]);
        if (deleted) {
            signalModifiedKey(c->db,c->argv[j]);
            notifyKeyspaceEvent(NOTIFY_GENERIC,
                "del",c->argv[j],c->db->id);
            server.dirty++;
            numdel++;
        }
    }
    addReplyLongLong(c,numdel);
}
  • dbAsyncDelete

In fact, there are conditions for asynchrony here

/* Delete a key, value, and associated expiration entry if any, from the DB.
 * If there are enough allocations to free the value object may be put into
 * a lazy free list instead of being freed synchronously. The lazy free list
 * will be reclaimed in a different bio.c thread. */
#define LAZYFREE_THRESHOLD 64
int dbAsyncDelete(redisDb *db, robj *key) {
    /* Deleting an entry from the expires dict will not free the sds of
    o
     * the key, because it is shared with the main dictionary. */
    if (dictSize(db->expires) > 0) dictDelete(db->expires,key->ptr);

    /* If the value is composed of a few allocations, to free in a lazy way
     * is actually just slower... So under a certain limit we just free
     * the object synchronously. */
    dictEntry *de = dictUnlink(db->dict,key->ptr);
    if (de) {
        robj *val = dictGetVal(de);
        size_t free_effort = lazyfreeGetFreeEffort(val);

        /* If releasing the object is too much work, do it in the background
         * by adding the object to the lazy free list.
         * Note that if the object is shared, to reclaim it now it is not
         * possible. This rarely happens, however sometimes the implementation
         * of parts of the Redis core may call incrRefCount() to protect
         * objects, and then call dbDelete(). In this case we'll fall
         * through and reach the dictFreeUnlinkedEntry() call, that will be
         * equivalent to just calling decrRefCount(). */
        if (free_effort > LAZYFREE_THRESHOLD && val->refcount == 1) {
            atomicIncr(lazyfree_objects,1);
            //Too much background processing released
            bioCreateBackgroundJob(BIO_LAZY_FREE,val,NULL,NULL);
            dictSetVal(db->dict,de,NULL);
        }
    }

    /* Release the key-val pair, or just the key if we set the val
     * field to NULL in order to lazy free it later. */
    if (de) {
        dictFreeUnlinkedEntry(db->dict,de);
        if (server.cluster_enabled) slotToKeyDel(key);
        return 1;
    } else {
        return 0;
    }
}
  • dbSyncDelete
/* Delete a key, value, and associated expiration entry if any, from the DB */
int dbSyncDelete(redisDb *db, robj *key) {
    /* Deleting an entry from the expires dict will not free the sds of
     * the key, because it is shared with the main dictionary. */
    if (dictSize(db->expires) > 0) dictDelete(db->expires,key->ptr);
    if (dictDelete(db->dict,key->ptr) == DICT_OK) {
        if (server.cluster_enabled) slotToKeyDel(key);
        return 1;
    } else {
        return 0;
    }
}

Recommended Today

Building spring cloud microservice framework: 2. Registration and discovery of spring cloud services

Build microservice framework (SC service registration and discovery) Source address of this article: build microservice framework (SC service registration and discovery) GitHub address: Squid Service registry Nacos Nacos is an open source registry middleware of Alibaba. Detailed introduction can visit the official website of Nacos. This framework is based on Nacos registration. To install Nacos, […]