Where are KEYS
, SCAN
, FLUSHDB
etc?
一些非常常见的重复出现的问题是:
似乎没有
Keys(...)
或Scan(...)
方法? 如何查询数据库中存在哪些键?
or
似乎没有
Flush(...)
方法? 如何删除数据库中的所有 keys?
这里的关键词是最后一个:数据库。因为 StackExchange.Redis 的目标是针对群集等场景,所以了解哪些命令针对 database(可以分布在多个节点上的逻辑数据库)以及哪些命令针对 server 很重要。以下命令均以单个服务器为目标:
KEYS
/SCAN
FLUSHDB
/FLUSHALL
RANDOMKEY
CLIENT
CLUSTER
CONFIG
/INFO
/TIME
REPLICAOF
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
仅列出当前服务器上的密钥;不是更广泛的逻辑数据库FLUSHDB
/FLUSHALL
只删除当前服务器上的密钥;不是更广泛的逻辑数据库RANDOMKEY
仅选择当前服务器上的密钥;不是更广泛的逻辑数据库
实际上,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()
调用中已选择目标数据库)不同,这些方法采用数据库的可选参数,或者默认为 0
。
Keys(...)
方法值得一提:它不具有 *Async
对应项,这是不寻常的。原因是系统将确定最适合使用的方法(根据服务器版本,使用 KEYS
或 SCAN
),并且在可能的情况下,将使用 SCAN
方法退回。 一个 IEnumerable<RedisKey>
在内部完成所有分页的操作:因此你无需查看游标操作的实现详细信息。如果 SCAN
不可用,它将使用 KEYS
,这可能会导致服务器阻塞。无论哪种方式,SCAN
和 KEYS
都需要清除整个密钥空间,因此应避免在生产服务器上使用,或至少应针对副本服务器。
我必须记住连接的服务器是哪个?
你可以使用 conn.GetEndPoints()
列出端点(所有端点或原始配置中指定的端点:不一定是同一件事),并使用 GetServer()
进行迭代以找到你要使用的服务器。