-
Notifications
You must be signed in to change notification settings - Fork 824
Fixed Cache fetch error on Redis Cluster #4056
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
f755bd6
to
6c8894b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just one question. Looks like a useful fix for people using Redis.
for i, val := range cmd.Val() { | ||
if val != nil { | ||
ret[i] = StringToBytes(val.(string)) | ||
_, isCluster := c.rdb.(*redis.ClusterClient) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a question to better understand the fix (I'm not an expect on Redis or the Go bindings).
This is working around an issue/limitation in the bindings, correct? Or a limitation in a particular server version? I only ask because my first reaction to this is that checking the type of an interface feels wrong. If it's the only option, then we'll have to live with it of course.
Either way, it might be nice to put a comment here to explain why we have to check the type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the review!
I thought the same thing, but I think this method is the simplest. The Redis client is initialized with the NewUniversalClient
.
This is the implementation.
https://github.com/go-redis/redis/blob/v8.8.0/universal.go#L199-L206
UniversalClient
can take Client
and ClusterClient
. Single node or sentinel if Client
is set. mget is always supported. Redis Cluster configuration if ClusterClient
is set. mget may not be supported.
The only way to check if the Universal Client is Redis Cluster is by type assertion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment.
6c8894b
to
612b98d
Compare
612b98d
to
2915141
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
2915141
to
d75dac2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. I don't know much about redis client, but given the comment, it looks reasonable.
pkg/chunk/cache/redis_client.go
Outdated
cmd := c.rdb.Get(ctx, key) | ||
if err := cmd.Err(); err != nil { | ||
return nil, err | ||
} | ||
ret[i] = StringToBytes(cmd.Val()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a key doesn't exist, then ret[i]
is expected to be nil
. I don't think it's the case here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pracucci thanks for reviewing! c.rdb.MGet(...).Val()
returns []interface{}
, but c.rdb.Get(...).Val()
returns string. If the value is not found, it will return an empty string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the value is not found, it will return an empty string.
I think this break the behaviour (see my previous comment above). Having a unit test to prove / disprove it would be great.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
understood. Thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Processed the empty values and added the tests. The tests confirm that the behavior is the same for Single and Cluster configurations of Redis.
@kamijin-fanta 👋 Would you have some time to take a look at my last comment, please? Thanks! |
cb7c71e
to
7d2ffa3
Compare
Can you please rebase against master to pull in #4137 and move the changelog entry to the top? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for addressing my feedback! The logic LGTM. I've left a couple of last comments and then we're good to go!
CHANGELOG.md
Outdated
@@ -73,6 +73,7 @@ | |||
* [BUGFIX] Frontend, Query-scheduler: allow querier to notify about shutdown without providing any authentication. #4066 | |||
* [BUGFIX] Querier: fixed race condition causing queries to fail right after querier startup with the "empty ring" error. #4068 | |||
* [BUGFIX] Compactor: Increment `cortex_compactor_runs_failed_total` if compactor failed compact a single tenant. #4094 | |||
* [BUGFIX] Fixed cache fetch error on Redis Cluster. #4056 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rebase master
and move this CHANGELOG entry to the top. We've cut 1.9 release in the meanwhile. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kamijin-fanta This commit is still valid. Could you address it, please?
pkg/chunk/cache/redis_client_test.go
Outdated
|
||
clients := []*RedisClient{single, cluster} | ||
for i, c := range clients { | ||
meg := []string{"run on single redis client", "run on cluster redis client"}[i] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a little convoluted. Instead of passing meg
(I guess you meant msg
) to each assertion function, you can run the test within a t.Run(description, func(t *testing.T) { /* your test logic here */})
and having the description only passed to t.Run()
.
Following this example, a common pattern is using table testing to define the test cases. As example, I'm picking a random test where we use table testing:
cortex/pkg/chunk/schema_config_test.go
Lines 306 to 312 in 5009276
func TestSchemaConfig_Validate(t *testing.T) { | |
t.Parallel() | |
tests := map[string]struct { | |
config *SchemaConfig | |
expected *SchemaConfig | |
err error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks. fixed to assigned name and client to slice.
3e7280d
to
34c9a9b
Compare
Signed-off-by: kamijin_fanta <[email protected]>
Signed-off-by: kamijin_fanta <[email protected]>
Signed-off-by: kamijin_fanta <[email protected]>
Signed-off-by: kamijin_fanta <[email protected]>
34c9a9b
to
afddc3f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kamijin-fanta! LGTM. Please address the comment in the CHANGELOG and then we can merge. Thanks again!
CHANGELOG.md
Outdated
@@ -73,6 +73,7 @@ | |||
* [BUGFIX] Frontend, Query-scheduler: allow querier to notify about shutdown without providing any authentication. #4066 | |||
* [BUGFIX] Querier: fixed race condition causing queries to fail right after querier startup with the "empty ring" error. #4068 | |||
* [BUGFIX] Compactor: Increment `cortex_compactor_runs_failed_total` if compactor failed compact a single tenant. #4094 | |||
* [BUGFIX] Fixed cache fetch error on Redis Cluster. #4056 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kamijin-fanta This commit is still valid. Could you address it, please?
What this PR does:
Redis Cluster may not support MGet. In that case, fall back to multiple Get.
Which issue(s) this PR fixes:
Fixes #4053
Checklist
CHANGELOG.md
updated - the order of entries should be[CHANGE]
,[FEATURE]
,[ENHANCEMENT]
,[BUGFIX]