@@ -134,6 +134,14 @@ class RedisCluster(AbstractRedis, AbstractRedisCluster, AsyncRedisClusterCommand
134
134
| Enable read from replicas in READONLY mode and defines the load balancing
135
135
strategy that will be used for cluster node selection.
136
136
The data read from replicas is eventually consistent with the data in primary nodes.
137
+ :param dynamic_startup_nodes:
138
+ | Set the RedisCluster's startup nodes to all the discovered nodes.
139
+ If true (default value), the cluster's discovered nodes will be used to
140
+ determine the cluster nodes-slots mapping in the next topology refresh.
141
+ It will remove the initial passed startup nodes if their endpoints aren't
142
+ listed in the CLUSTER SLOTS output.
143
+ If you use dynamic DNS endpoints for startup nodes but CLUSTER SLOTS lists
144
+ specific IP addresses, it is best to set it to false.
137
145
:param reinitialize_steps:
138
146
| Specifies the number of MOVED errors that need to occur before reinitializing
139
147
the whole cluster topology. If a MOVED error occurs and the cluster does not
@@ -250,6 +258,7 @@ def __init__(
250
258
require_full_coverage : bool = True ,
251
259
read_from_replicas : bool = False ,
252
260
load_balancing_strategy : Optional [LoadBalancingStrategy ] = None ,
261
+ dynamic_startup_nodes : bool = True ,
253
262
reinitialize_steps : int = 5 ,
254
263
cluster_error_retry_attempts : int = 3 ,
255
264
max_connections : int = 2 ** 31 ,
@@ -390,6 +399,7 @@ def __init__(
390
399
startup_nodes ,
391
400
require_full_coverage ,
392
401
kwargs ,
402
+ dynamic_startup_nodes = dynamic_startup_nodes ,
393
403
address_remap = address_remap ,
394
404
event_dispatcher = self ._event_dispatcher ,
395
405
)
@@ -1164,6 +1174,7 @@ async def _mock(self, error: RedisError):
1164
1174
1165
1175
class NodesManager :
1166
1176
__slots__ = (
1177
+ "_dynamic_startup_nodes" ,
1167
1178
"_moved_exception" ,
1168
1179
"_event_dispatcher" ,
1169
1180
"connection_kwargs" ,
@@ -1181,6 +1192,7 @@ def __init__(
1181
1192
startup_nodes : List ["ClusterNode" ],
1182
1193
require_full_coverage : bool ,
1183
1194
connection_kwargs : Dict [str , Any ],
1195
+ dynamic_startup_nodes : bool = True ,
1184
1196
address_remap : Optional [Callable [[Tuple [str , int ]], Tuple [str , int ]]] = None ,
1185
1197
event_dispatcher : Optional [EventDispatcher ] = None ,
1186
1198
) -> None :
@@ -1193,6 +1205,8 @@ def __init__(
1193
1205
self .nodes_cache : Dict [str , "ClusterNode" ] = {}
1194
1206
self .slots_cache : Dict [int , List ["ClusterNode" ]] = {}
1195
1207
self .read_load_balancer = LoadBalancer ()
1208
+
1209
+ self ._dynamic_startup_nodes : bool = dynamic_startup_nodes
1196
1210
self ._moved_exception : MovedError = None
1197
1211
if event_dispatcher is None :
1198
1212
self ._event_dispatcher = EventDispatcher ()
@@ -1435,8 +1449,10 @@ async def initialize(self) -> None:
1435
1449
# Set the tmp variables to the real variables
1436
1450
self .slots_cache = tmp_slots
1437
1451
self .set_nodes (self .nodes_cache , tmp_nodes_cache , remove_old = True )
1438
- # Populate the startup nodes with all discovered nodes
1439
- self .set_nodes (self .startup_nodes , self .nodes_cache , remove_old = True )
1452
+
1453
+ if self ._dynamic_startup_nodes :
1454
+ # Populate the startup nodes with all discovered nodes
1455
+ self .set_nodes (self .startup_nodes , self .nodes_cache , remove_old = True )
1440
1456
1441
1457
# Set the default node
1442
1458
self .default_node = self .get_nodes_by_server_type (PRIMARY )[0 ]
0 commit comments