1
0
mirror of https://github.com/redis/go-redis.git synced 2025-07-28 06:42:00 +03:00

Set correct cluster slot for scan commands, similarly to Java's Jedis client (#2623)

- At present, the `scan` command is dispatched to a random slot.
- As far as I can tell, the scanX family of commands are not cluster aware (e.g. don't redirect the client to the correct slot).
- You can see [here](869dc0bb66/src/main/java/redis/clients/jedis/ShardedCommandObjects.java (L101)), the Jedis client calling `processKey` on the match argument, and this is what this PR also does.

We've had this patch running in production, and it seems to work well for us.

For further thought:
- Continuing looking at other Redis clients (e.g. Jedis), they outright [reject as invalid](869dc0bb66/src/main/java/redis/clients/jedis/ShardedCommandObjects.java (L98)) any scan command that does not include a hash-tag. Presumably this has the advantage of users not being surprised when their scan produces no results when a random server is picked.
- Perhaps it would be sensible for go-redis to do the same also?

Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com>
This commit is contained in:
Pete Woods
2025-06-24 11:43:03 +01:00
committed by GitHub
parent 0383d08a35
commit 4ac591c7c4
6 changed files with 66 additions and 1 deletions

View File

@ -3,6 +3,8 @@ package redis
import (
"context"
"time"
"github.com/redis/go-redis/v9/internal/hashtag"
)
type HashCmdable interface {
@ -192,6 +194,9 @@ func (c cmdable) HScan(ctx context.Context, key string, cursor uint64, match str
args = append(args, "count", count)
}
cmd := NewScanCmd(ctx, c, args...)
if hashtag.Present(match) {
cmd.SetFirstKeyPos(4)
}
_ = c(ctx, cmd)
return cmd
}
@ -211,6 +216,9 @@ func (c cmdable) HScanNoValues(ctx context.Context, key string, cursor uint64, m
}
args = append(args, "novalues")
cmd := NewScanCmd(ctx, c, args...)
if hashtag.Present(match) {
cmd.SetFirstKeyPos(4)
}
_ = c(ctx, cmd)
return cmd
}