语法:
keys pattern
返回所有符合pattern的key
支持 glob-style patterns:
h?llo
matcheshello
,hallo
andhxllo
h*llo
matcheshllo
andheeeello
h[ae]llo
matcheshello
andhallo,
but nothillo
h[^e]llo
matcheshallo
,hbllo
, ... but nothello
h[a-b]llo
matcheshallo
andhbllo
源码分析
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);
}
上面的源码中可以看到:
- keys 需要遍历全部key
- 遍历的所有的key都要和pattern 进行比较
所以在生产环境中,要很谨慎使用keys 命令,避免遍历过多的key而阻塞。