Skip to content

Conversation

devbini
Copy link

@devbini devbini commented Aug 8, 2025

Make sure that:

  • You have read the contribution guidelines.
  • You have created a feature request first to discuss your contribution intent. Please reference the feature request ticket number in the pull request.
  • You applied code formatting rules using the mvn formatter:format target. Don’t submit any formatting related changes.
  • You submit test cases (unit or integration tests) that back your changes.

Summary

This pull request resolves issue #2432, which was discussed and marked as status: help-wanted.

When an MGET command is executed in a Redis Cluster environment, the internal logic now checks the number of keys for each slot-based partition. If a partition contains only a single key, this change translates the command to a more lightweight GET instead of MGET.

This optimization reduces unnecessary overhead on both the client and server, improving throughput and lowering latency. This is especially effective in applications where single-key MGET calls occur frequently.

Changes

  • src/main/java/io/lettuce/core/cluster/RedisAdvancedClusterAsyncCommandsImpl.java

    • Modified mget(Iterable<K> keys) to check the number of keys per partition.
    • If a partition contains only one key, it now dispatches a GET command.
    • If a partition contains multiple keys, it retains the existing behavior of dispatching an MGET command for that partition.
  • src/test/java/io/lettuce/core/cluster/commands/StringClusterCommandIntegrationTests.java

    • Added the mgetOptimization integration test.
    • This test creates two keys on different slots using hash tags, calls the mget method, verifies the result, and cleans up the keys afterward.

Testing

Using the Redis Cluster environment launched via src/test/resources/docker-env/docker-compose.yml, I have verified the behavior change with the MONITOR command.

Before (Original Code):
The client sends an MGET command for each key, even when there's only one key for the slot.

...$ redis-cli -p 7379 MONITOR
...
1754637572.821032 [0 [172.18.0.1:59736](http://172.18.0.1:59736/)] "SET" "{slot-a}:test" "value-a"
1754637572.824821 [0 [172.18.0.1:59736](http://172.18.0.1:59736/)] "SET" "{slot-b}:test" "value-b"

1754637572.833766 [0 [172.18.0.1:59736](http://172.18.0.1:59736/)] "MGET" "{slot-b}:test"
1754637572.834413 [0 [172.18.0.1:59736](http://172.18.0.1:59736/)] "MGET" "{slot-a}:test"

1754637572.842009 [0 [172.18.0.1:59736](http://172.18.0.1:59736/)] "DEL" "{slot-b}:test"
1754637572.842053 [0 [172.18.0.1:59736](http://172.18.0.1:59736/)] "DEL" "{slot-a}:test"
...

After (With this PR):
The client now correctly sends a GET command for each single-key partition.

...$ redis-cli -p 7379 MONITOR
...
1754637500.361643 [0 [172.18.0.1:34086](http://172.18.0.1:34086/)] "SET" "{slot-a}:test" "value-a"
1754637500.364315 [0 [172.18.0.1:34086](http://172.18.0.1:34086/)] "SET" "{slot-b}:test" "value-b"

1754637500.367065 [0 [172.18.0.1:34086](http://172.18.0.1:34086/)] "GET" "{slot-b}:test"
1754637500.367496 [0 [172.18.0.1:34086](http://172.18.0.1:34086/)] "GET" "{slot-a}:test"

1754637500.371618 [0 [172.18.0.1:34086](http://172.18.0.1:34086/)] "DEL" "{slot-b}:test"
1754637500.374739 [0 [172.18.0.1:34086](http://172.18.0.1:34086/)] "DEL" "{slot-a}:test"
...

This confirms that the optimization is working as intended.


Thank you for the opportunity to contribute.
This is my first pull request to the project, so I'm still getting familiar with the contribution process. I'm more than happy to make any changes and welcome all feedback 🤗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants