Skip to content

Commit

Permalink
Explain server vs database commands; recurring FAQ
Browse files Browse the repository at this point in the history
  • Loading branch information
mgravell committed Apr 15, 2014
1 parent 04e837d commit ef57a95
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
1 change: 1 addition & 0 deletions Docs/Docs.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<Link>README.md</Link>
</None>
<None Include="Basics.md" />
<None Include="KeysScan.md" />
<None Include="Events.md" />
<None Include="Configuration.md" />
<None Include="ExecSync.md" />
Expand Down
53 changes: 53 additions & 0 deletions Docs/KeysScan.md
Original file line number Diff line number Diff line change
@@ -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<RedisKey>` 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).
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
---
Expand Down

0 comments on commit ef57a95

Please sign in to comment.