如何在Redis中实现Key *?

时间:2014-02-21 07:20:09

标签: redis memcached distributed-caching

我想知道Redis Key *的内部实现。 我正在实现分布式缓存功能。

1 个答案:

答案 0 :(得分:2)

“KEYS *”命令的内部行为是线性扫描主字典以收集所有键,并构建结果。过期的密钥不包括在内。以下是实施:

void keysCommand(redisClient *c) {
    dictIterator *di;
    dictEntry *de;
    sds pattern = c->argv[1]->ptr;
    int plen = sdslen(pattern), allkeys;
    unsigned long numkeys = 0;
    void *replylen = addDeferredMultiBulkLength(c);

    di = dictGetSafeIterator(c->db->dict);
    allkeys = (pattern[0] == '*' && pattern[1] == '\0');
    while((de = dictNext(di)) != NULL) {
        sds key = dictGetKey(de);
        robj *keyobj;

        if (allkeys || stringmatchlen(pattern,plen,key,sdslen(key),0)) {
            keyobj = createStringObject(key,sdslen(key));
            if (expireIfNeeded(c->db,keyobj) == 0) {
                addReplyBulk(c,keyobj);
                numkeys++;
            }
            decrRefCount(keyobj);
        }
    }
    dictReleaseIterator(di);
    setDeferredMultiBulkLength(c,replylen,numkeys);
}

发生此操作时,Redis服务器上不能执行其他命令,事件循环在KEYS命令的结果上处于挂起状态。如果密钥数量很高(> 10K),客户端会发现服务器不再响应。

这是一个仅用于调试目的的命令。不要在应用程序中使用它。