Redis原理:keys命令

发布于:2025-04-09 ⋅ 阅读:(34) ⋅ 点赞:(0)

语法:

keys pattern

返回所有符合pattern的key

支持 glob-style patterns:

  • h?llo matches hello, hallo and hxllo
  • h*llo matches hllo and heeeello
  • h[ae]llo matches hello and hallo, but not hillo
  • h[^e]llo matches hallo, hbllo, ... but not hello
  • h[a-b]llo matches hallo and hbllo

源码分析

void keysCommand(client *c)
{
    dictIterator *di;
    dictEntry *de;
    // 获取当前的匹配模式
    sds pattern = c->argv[1]->ptr;
    int plen = sdslen(pattern), allkeys;
    unsigned long numkeys = 0;
    void *replylen = addReplyDeferredLen(c);
    // 获取数据字典的迭代器
    di = dictGetSafeIterator(c->db->dict);
    // 判断是否获取全部
    allkeys = (pattern[0] == '*' && plen == 1);
    // 遍历迭代器
    while ((de = dictNext(di)) != NULL)
    {
        // 获取当前遍历的key
        sds key = dictGetKey(de);
        robj *keyobj;
        // 如果是获取全部key 或是 当前的key符合匹配模式
        if (allkeys || stringmatchlen(pattern, plen, key, sdslen(key), 0))
        {
            // 当前当前的key转换成robj对象
            keyobj = createStringObject(key, sdslen(key));
            // 如果key没有过期,则加入响应缓存
            if (!keyIsExpired(c->db, keyobj))
            {
                addReplyBulk(c, keyobj);
                numkeys++;
            }
            decrRefCount(keyobj);
        }
    }
    // 遍历结束,释放对象
    dictReleaseIterator(di);
    setDeferredArrayLen(c, replylen, numkeys);
}

上面的源码中可以看到:

  1. keys 需要遍历全部key
  2. 遍历的所有的key都要和pattern 进行比较

所以在生产环境中,要很谨慎使用keys 命令,避免遍历过多的key而阻塞。


网站公告

今日签到

点亮在社区的每一天
去签到