@@ -133,6 +133,14 @@ class RedisCluster(AbstractRedis, AbstractRedisCluster, AsyncRedisClusterCommand
133
133
| Enable read from replicas in READONLY mode. You can read possibly stale data.
134
134
When set to true, read commands will be assigned between the primary and
135
135
its replications in a Round-Robin manner.
136
+ :param dynamic_startup_nodes:
137
+ | Set the RedisCluster's startup nodes to all the discovered nodes.
138
+ If true (default value), the cluster's discovered nodes will be used to
139
+ determine the cluster nodes-slots mapping in the next topology refresh.
140
+ It will remove the initial passed startup nodes if their endpoints aren't
141
+ listed in the CLUSTER SLOTS output.
142
+ If you use dynamic DNS endpoints for startup nodes but CLUSTER SLOTS lists
143
+ specific IP addresses, it is best to set it to false.
136
144
:param reinitialize_steps:
137
145
| Specifies the number of MOVED errors that need to occur before reinitializing
138
146
the whole cluster topology. If a MOVED error occurs and the cluster does not
@@ -233,6 +241,7 @@ def __init__(
233
241
startup_nodes : Optional [List ["ClusterNode" ]] = None ,
234
242
require_full_coverage : bool = True ,
235
243
read_from_replicas : bool = False ,
244
+ dynamic_startup_nodes : bool = True ,
236
245
reinitialize_steps : int = 5 ,
237
246
cluster_error_retry_attempts : int = 3 ,
238
247
connection_error_retry_attempts : int = 3 ,
@@ -370,6 +379,7 @@ def __init__(
370
379
startup_nodes ,
371
380
require_full_coverage ,
372
381
kwargs ,
382
+ dynamic_startup_nodes = dynamic_startup_nodes ,
373
383
address_remap = address_remap ,
374
384
)
375
385
self .encoder = Encoder (encoding , encoding_errors , decode_responses )
@@ -1093,6 +1103,7 @@ class NodesManager:
1093
1103
"require_full_coverage" ,
1094
1104
"slots_cache" ,
1095
1105
"startup_nodes" ,
1106
+ "_dynamic_startup_nodes" ,
1096
1107
"address_remap" ,
1097
1108
)
1098
1109
@@ -1101,11 +1112,13 @@ def __init__(
1101
1112
startup_nodes : List ["ClusterNode" ],
1102
1113
require_full_coverage : bool ,
1103
1114
connection_kwargs : Dict [str , Any ],
1115
+ dynamic_startup_nodes : bool = True ,
1104
1116
address_remap : Optional [Callable [[Tuple [str , int ]], Tuple [str , int ]]] = None ,
1105
1117
) -> None :
1106
1118
self .startup_nodes = {node .name : node for node in startup_nodes }
1107
1119
self .require_full_coverage = require_full_coverage
1108
1120
self .connection_kwargs = connection_kwargs
1121
+ self ._dynamic_startup_nodes = dynamic_startup_nodes
1109
1122
self .address_remap = address_remap
1110
1123
1111
1124
self .default_node : "ClusterNode" = None
@@ -1338,8 +1351,10 @@ async def initialize(self) -> None:
1338
1351
# Set the tmp variables to the real variables
1339
1352
self .slots_cache = tmp_slots
1340
1353
self .set_nodes (self .nodes_cache , tmp_nodes_cache , remove_old = True )
1341
- # Populate the startup nodes with all discovered nodes
1342
- self .set_nodes (self .startup_nodes , self .nodes_cache , remove_old = True )
1354
+
1355
+ if self ._dynamic_startup_nodes :
1356
+ # Populate the startup nodes with all discovered nodes
1357
+ self .set_nodes (self .startup_nodes , self .nodes_cache , remove_old = True )
1343
1358
1344
1359
# Set the default node
1345
1360
self .default_node = self .get_nodes_by_server_type (PRIMARY )[0 ]
0 commit comments