From ef57a959d7798d53212474a7e3bf3365c1a9a6fc Mon Sep 17 00:00:00 2001 From: Marc Gravell Date: Tue, 15 Apr 2014 11:23:38 +0100 Subject: [PATCH] Explain server vs database commands; recurring FAQ --- Docs/Docs.csproj | 1 + Docs/KeysScan.md | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 3 files changed, 55 insertions(+) create mode 100644 Docs/KeysScan.md diff --git a/Docs/Docs.csproj b/Docs/Docs.csproj index 6b1f1462e..7b74696de 100644 --- a/Docs/Docs.csproj +++ b/Docs/Docs.csproj @@ -45,6 +45,7 @@ README.md + diff --git a/Docs/KeysScan.md b/Docs/KeysScan.md new file mode 100644 index 000000000..9ad7715df --- /dev/null +++ b/Docs/KeysScan.md @@ -0,0 +1,53 @@ +Where are `KEYS`, `SCAN`, `FLUSHDB`, `FLUSHALL` ? +=== + +Some very common recurring questions are: + +> There doesn't seem to be a `Keys(...)` or `Scan(...)` method? How can I query which keys exist in the database? + +or + +> There doesn't seem to be a `Flush(...)` method? How can I remove all the keys in the database? + +The key word here, oddly enough, is the last one: database. Because StackExchange.Redis aims to target scenarios such as cluster, it is important to know which commands target the *database* (the logical database that could be distributed over multiple nodes), and which commands target the *server*. These commands: + +- `KEYS` / `SCAN` +- `FLUSHDB` / `FLUSHALL` +- `RANDOMKEY` +- `CLIENT *` +- `CLUSTER *` +- `CONFIG` / `INFO` / `TIME` +- `SLAVEOF` +- `SAVE` / `BGSAVE` / `LASTSAVE` +- `SCRIPT` (not to be confused with `EVAL` / `EVALSHA`) +- `SHUTDOWN` +- `SLOWLOG` +- `PUBSUB *` (not to be confused with `PUBLISH` / `SUBSCRIBE` / etc) + +(I've probably missed at least one) Most of these will seem pretty obvious, but the first 3 rows are not so obvious: + +- `KEYS` / `SCAN` only list keys that are on the current server; not the wider logical database +- `FLUSHDB` / `FLUSHALL` only remove keys that are on the current server; not the wider logical database +- `RANDOMKEY` only selects a key that is on the current server; not the wider logical database + +Actually, StackExchange.Redis spoofs the `RANDOMKEY` one on the `IDatabase` API by simply selecting a target server at random, but this is not possible for the others. + +So how do I use them? +=== + +Simple: start from a server, not a database. + + var server = conn.GetServer(someServer); + foreach(var key in server.Keys(pattern: "*foo*")) { + Console.WriteLine(key); + } + server.FlushDatabase(); + +Note that unlike the `IDatabase` API (where the target database has already been selected in the `GetDatabase()` call), these methods take an optional parameter for the database, or it defaults to `0`. + +The `Keys(...)` method deserves special mention: it is unusual in that it does not have an `*Async` counterpart. The reason for this is that behind the scenes, the system will determine the most appropriate method to use (`KEYS` vs `SCAN`, based on the server version), and if possible will use the `SCAN` approach to hand you back an `IEnumerable` that does all the paging internally - so you never need to see the implementation details of the cursor operations. If `SCAN` is not available, it will use `KEYS`, which can cause blockages at the server. Either way, both `SCAN` and `KEYS` will need to sweep the entire keyspace, so should be avoided on production servers - or at least, targeted at slaves. + +So I need to remember which server I connected to? That sucks! +=== + +No, not quite. You can use `conn.GetEndPoints()` to list the endpoints (either all known, or the ones specified in the original configuration - these are not necessarily the same thing), and iterate with `GetServer()` to find the server you want (for example, selecting a slave). diff --git a/README.md b/README.md index 6347c4a28..eb68f2a08 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Documentation - [Transactions](https://github.com/StackExchange/StackExchange.Redis/blob/master/Docs/Transactions.md) - how atomic transactions work in redis - [Events](https://github.com/StackExchange/StackExchange.Redis/blob/master/Docs/Events.md) - the events available for logging / information purposes - [Pub/Sub Message Order](https://github.com/StackExchange/StackExchange.Redis/blob/master/Docs/PubSubOrder.md) - advice on sequential and concurrent processing +- [Where are `KEYS` / `SCAN` / `FLUSH*`?](https://github.com/StackExchange/StackExchange.Redis/blob/master/Docs/KeysScan.md) - how to use server-based commands Questions and Contributions ---