Skip to content
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

[4.x] Fix how hash slot assignment is retrieved and stored #407

Merged
merged 2 commits into from
Oct 11, 2023

Conversation

Ladicek
Copy link
Contributor

@Ladicek Ladicek commented Sep 20, 2023

Backport of #405 to 4.x.

@Ladicek Ladicek changed the title Fix how hash slot assignment is retrieved and stored [4.x] Fix how hash slot assignment is retrieved and stored Sep 20, 2023
@Ladicek
Copy link
Contributor Author

Ladicek commented Sep 20, 2023

The test failure is not caused by this PR, it fails on the current 4.x branch too (as well as in #406).

@vietj
Copy link
Contributor

vietj commented Sep 21, 2023

thanks @Ladicek let me fix the build and then you can rebase :-)

}
}
}

private void getSlots(String endpoint, RedisConnection conn, Handler<AsyncResult<Slots>> onGetSlots) {
private Future<Slots> getSlots() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead here we should have a context

private Future<Slots> getSlots() {
Slots slots = this.slots.get();
if (slots != null) {
return Future.succeededFuture(slots);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and use context.succeededFuture(slot)

return Future.succeededFuture(slots);
}

Promise<Slots> promise = vertx.promise();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or context.promise()

Previously, the `RedisClusterClient` used to obtain the hash slot
assignment as the first step of each `connect()` call. This is fairly
expensive and increases the load on the first endpoint in the list
(because we target the first endpoint when issuing `CLUSTER SLOTS`).

It is also unnecessary. Redis always sends a redirection when the node
to which a command is sent is not assigned the hash slot targetted
by the command. Until we observe such redirection, the hash slot
assignment we observed before is still valid. Hence, we can store
the hash slot assignment in the `RedisClusterClient` and reuse it
for all `RedisClusterConnection` objects, until the `MOVED` error
is seen. In such case, we reset the hash slot assignment so that
the next `connect()` call fetches it again.

To avoid spurious failures (it could happen that the cluster is
resharded such that a command that would fail under the existing
hash slot assignment will no longer fail, because the hash slots
that were previously assigned to multiple nodes are now assigned
to a single node), the hash slot assignment is not kept permanently.
Instead, it is treated as a cache with configurable TTL, defaulting
to 1 second.
@Ladicek Ladicek force-pushed the fix-cluster-slots-retrieval-4.x branch from f1025a5 to 7a25220 Compare September 25, 2023 15:24
@Ladicek
Copy link
Contributor Author

Ladicek commented Sep 25, 2023

Refactored as discussed on Friday:

  • the hash slot assignment is not stored permanently; instead, it is treated as a cache with configurable TTL (defaults to 1 second)
  • avoided the storm of hash slot retrieval after the cache expired by storing Future<Slots> instead of simple Slots

@vietj vietj added this to the 4.5.0 milestone Oct 11, 2023
@vietj vietj merged commit 5e5c2a2 into vert-x3:4.x Oct 11, 2023
4 checks passed
@Ladicek Ladicek deleted the fix-cluster-slots-retrieval-4.x branch October 11, 2023 06:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants