diff --git a/src/main/java/io/lettuce/core/cluster/ClusterScanSupport.java b/src/main/java/io/lettuce/core/cluster/ClusterScanSupport.java index 76ab91d4cf..b5b5a3e08c 100644 --- a/src/main/java/io/lettuce/core/cluster/ClusterScanSupport.java +++ b/src/main/java/io/lettuce/core/cluster/ClusterScanSupport.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.concurrent.ThreadLocalRandom; import java.util.function.Function; import reactor.core.publisher.Mono; @@ -158,7 +159,13 @@ public Iterator iterator() { }); if (!selection.isEmpty()) { - RedisClusterNode selectedNode = (RedisClusterNode) selection.get(0); + + int indexToUse = 0; + if (!OrderingReadFromAccessor.isOrderSensitive(connection.getReadFrom())) { + indexToUse = ThreadLocalRandom.current().nextInt(selection.size()); + } + + RedisClusterNode selectedNode = (RedisClusterNode) selection.get(indexToUse); nodeIds.add(selectedNode.getNodeId()); continue; } diff --git a/src/test/java/io/lettuce/core/cluster/ScanIteratorIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/ScanIteratorIntegrationTests.java index fdef446eb0..130849db39 100644 --- a/src/test/java/io/lettuce/core/cluster/ScanIteratorIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/ScanIteratorIntegrationTests.java @@ -49,6 +49,7 @@ class ScanIteratorIntegrationTests extends TestSupport { @Inject ScanIteratorIntegrationTests(StatefulRedisClusterConnection connection) { this.connection = connection; + this.connection.setReadFrom(ReadFrom.MASTER); this.redis = connection.sync(); } @@ -103,6 +104,19 @@ void keysMultiPass() { assertThat(keys).containsAll(KeysAndValues.KEYS); } + @Test + void keysMultiPassFromAnyNode() { + + redis.mset(KeysAndValues.MAP); + this.connection.setReadFrom(ReadFrom.ANY); + + ScanIterator scan = ScanIterator.scan(redis); + + List keys = scan.stream().collect(Collectors.toList()); + + assertThat(keys).containsAll(KeysAndValues.KEYS); + } + @Test void hscanShouldThrowNoSuchElementExceptionOnEmpty() {