KEYS
, SCAN
, FLUSHDB
方法在哪?
经常有人问这些问题:
好像并没有看到
Keys(...)
或者Scan(...)
方法?那我要怎么查询数据库里面存有哪些key?
或者
好像没有
Flush(...)
方法?那我要怎么清除数据库里面的所有key?
问题的关键就在这里:数据库。因为StackExchange.Redis旨在cluster等场景,知道哪些命令的目标是database(逻辑数据库可以分布在多个节点上)和哪些命令的目标是server是很重要的。下面的命令的目标全部指向一个单独server:
KEYS
/SCAN
FLUSHDB
/FLUSHALL
RANDOMKEY
CLIENT
CLUSTER
CONFIG
/INFO
/TIME
SLAVEOF
SAVE
/BGSAVE
/LASTSAVE
SCRIPT
(not to be confused withEVAL
/EVALSHA
)SHUTDOWN
SLOWLOG
PUBSUB
(not to be confused withPUBLISH
/SUBSCRIBE
/ etc)- some
DEBUG
operations
(我可能会漏掉不止一个。。。)他们当中大部分都可以很明显的看出来,除了前面三个:
KEYS
/SCAN
只会列出当前server上的keys:而不是整个逻辑数据库FLUSHDB
/FLUSHALL
同样只会移除当前server上的所有的keysRANDOMKEY
同样只会选出当前服务器上的一个key
事实上,StackExchange.Redis在 IDatabase
API 实现RANDOMKEY
的方式是随机选择一个目标服务器,对于其他的命令是不能这样做的。
那我要怎么使用这些命令呢?
很简单:从server上使用这些命令,而不是database。
// get the target server
var server = conn.GetServer(someServer);
// show all keys in database 0 that include "foo" in their name
foreach(var key in server.Keys(pattern: "*foo*")) {
Console.WriteLine(key);
}
// completely wipe ALL keys from database 0
server.FlushDatabase();
要注意不像IDatabase
API(在调用 GetDatabase()
就已经选好了target database),这些方法对database都有一个可选的参数,或者默认为0
。
Keys(...)
方法需要特别注意的是:它的与众不同之处在于它没有对应的*Async
方法。原因是在scene下,系统会判断出最适合采用的方法(KEYS
vs SCAN
,基于服务器版本),而且如果可以的话将会使用SCAN
在内部处理分页的方式返回一个IEnumerable<RedisKey>
-所以并不需要知道当前操作的实现细节。如果SCAN
不可用,将会采用KEYS
,这将会造成服务器阻塞,无论哪一种方式,SCAN
and KEYS
需要遍历整个key控件,所以在production server要避免使用这个方法-至少,在从服务器上使用。
那我就需要记住我连接是哪一台服务器?that sucks。。。
不,并不需要。你可以使用conn.GetEndPoints()
列出节点(或者是所有已知的,或者在config当中指出来的-两者不一定是相同的),然后使用GetServer()
迭代查处需要的server(例如:选择一个slave)