Skip to content

Commit

Permalink
docs: fix readme about MGET, MSET and DEL commands
Browse files Browse the repository at this point in the history
  • Loading branch information
supercaracal committed Sep 5, 2024
1 parent 981c020 commit af2662c
Showing 1 changed file with 46 additions and 21 deletions.
67 changes: 46 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,41 +138,66 @@ The `#pubsub` method supports sharded subscriptions.
Every interface handles redirections and resharding states internally.

## Multiple keys and CROSSSLOT error
A subset of commands can be passed multiple keys. But it has a constraint the keys are in the same hash slot.
The following error occurs because keys must be in the same hash slot and not just the same node.
A subset of commands can be passed multiple keys.
In cluster mode, these commands have a constraint that passed keys should belong to the same slot
and not just the same node.
Therefore, The following error occurs:

```ruby
cli = RedisClient.cluster.new_client
```
$ redis-cli mget key1 key2 key3
(error) CROSSSLOT Keys in request don't hash to the same slot
$ redis-cli cluster keyslot key1
(integer) 9189
cli.call('MGET', 'key1', 'key2', 'key3')
#=> CROSSSLOT Keys in request don't hash to the same slot (RedisClient::CommandError)
$ redis-cli cluster keyslot key2
(integer) 4998
cli.call('CLUSTER', 'KEYSLOT', 'key1')
#=> 9189
$ redis-cli cluster keyslot key3
(integer) 935
```

cli.call('CLUSTER', 'KEYSLOT', 'key2')
#=> 4998
For the constraint, Redis cluster provides a feature to be able to bias keys to the same slot with a hash tag.

cli.call('CLUSTER', 'KEYSLOT', 'key3')
#=> 935
```
$ redis-cli mget {key}1 {key}2 {key}3
1) (nil)
2) (nil)
3) (nil)
Also, you can use the hash tag to bias keys to the same slot.
$ redis-cli cluster keyslot {key}1
(integer) 12539
```ruby
cli.call('CLUSTER', 'KEYSLOT', '{key}1')
#=> 12539
$ redis-cli cluster keyslot {key}2
(integer) 12539
cli.call('CLUSTER', 'KEYSLOT', '{key}2')
#=> 12539
$ redis-cli cluster keyslot {key}3
(integer) 12539
```

cli.call('CLUSTER', 'KEYSLOT', '{key}3')
#=> 12539
In addition, this gem works multiple keys without a hash tag in MGET, MSET and DEL commands
using pipelining internally automatically.
If the first key includes a hash tag, this gem sends the command to the node as is.
If the first key doesn't have a hash tag, this gem converts the command into a single-key command
and sends them to nodes with pipelining, then gathering replies and returning them.

cli.call('MGET', '{key}1', '{key}2', '{key}3')
```ruby
r = RedisClient.cluster.new_client
#=> #<RedisClient::Cluster 127.0.0.1:6379>

r.call('mget', 'key1', 'key2', 'key3')
#=> [nil, nil, nil]

r.call('mget', '{key}1', '{key}2', '{key}3')
#=> [nil, nil, nil]
```

This behavior is for upper libraries to be able to keep a compatibility with a standalone client.
You can exploit this behavior for migrating from a standalone server to a cluster.
Although multiple calles with single-key comamnds are slower than pipelining,
the performance of the pipelined commands are slower than a single-slot query with multiple keys.
We recommend to use a hash tag in this use cases for the performance.

## Transactions
This gem supports [Redis transactions](https://redis.io/topics/transactions), including atomicity with `MULTI`/`EXEC`,
and conditional execution with `WATCH`. Redis does not support cross-node transactions, so all keys used within a
Expand Down

0 comments on commit af2662c

Please sign in to comment.