11package redis .clients .jedis ;
22
33import java .util .ArrayList ;
4+ import java .util .Collections ;
45import java .util .HashMap ;
56import java .util .List ;
67import java .util .Map ;
1314
1415import org .apache .commons .pool2 .impl .GenericObjectPoolConfig ;
1516
17+ import redis .clients .jedis .exceptions .JedisConnectionException ;
18+ import redis .clients .jedis .exceptions .JedisException ;
1619import redis .clients .util .SafeEncoder ;
1720
1821public class JedisClusterInfoCache {
@@ -77,39 +80,34 @@ public void discoverClusterNodesAndSlots(Jedis jedis) {
7780 }
7881 }
7982
80- public void discoverClusterSlots (Jedis jedis ) {
83+ public void renewClusterSlots (Jedis jedis ) {
8184 //If rediscovering is already in process - no need to start one more same rediscovering, just return
8285 if (!rediscovering ) {
83- w .lock ();
84- rediscovering = true ;
85-
8686 try {
87- List <Object > slots = jedis .clusterSlots ();
88-
89- // We should clear slots after getting result about cluster slots, because if we got exception or timeout in
90- // getting new slots state, which is possible, because it's an external operation - we could got empty slots collection
91- // and ton of new Jedis instances for random nodes, see JedisSlotBasedConnectionHandler#getConnectionFromSlot
92- this .slots .clear ();
93-
94- for (Object slotInfoObj : slots ) {
95- List <Object > slotInfo = (List <Object >) slotInfoObj ;
96-
97- if (slotInfo .size () <= MASTER_NODE_INDEX ) {
98- continue ;
87+ w .lock ();
88+ rediscovering = true ;
89+
90+ if (jedis != null ) {
91+ try {
92+ discoverClusterSlots (jedis );
93+ return ;
94+ } catch (JedisException e ) {
95+ //try nodes from all pools
9996 }
97+ }
10098
101- List <Integer > slotNums = getAssignedSlotArray (slotInfo );
102-
103- // hostInfos
104- List <Object > hostInfos = (List <Object >) slotInfo .get (MASTER_NODE_INDEX );
105- if (hostInfos .isEmpty ()) {
106- continue ;
99+ for (JedisPool jp : getShuffledNodesPool ()) {
100+ try {
101+ jedis = jp .getResource ();
102+ discoverClusterSlots (jedis );
103+ return ;
104+ } catch (JedisConnectionException e ) {
105+ // try next nodes
106+ } finally {
107+ if (jedis != null ) {
108+ jedis .close ();
109+ }
107110 }
108-
109- // at this time, we just use master, discard slave information
110- HostAndPort targetNode = generateHostAndPort (hostInfos );
111-
112- assignSlotsToNode (slotNums , targetNode );
113111 }
114112 } finally {
115113 rediscovering = false ;
@@ -118,6 +116,31 @@ public void discoverClusterSlots(Jedis jedis) {
118116 }
119117 }
120118
119+ private void discoverClusterSlots (Jedis jedis ) {
120+ List <Object > slots = jedis .clusterSlots ();
121+ this .slots .clear ();
122+
123+ for (Object slotInfoObj : slots ) {
124+ List <Object > slotInfo = (List <Object >) slotInfoObj ;
125+
126+ if (slotInfo .size () <= MASTER_NODE_INDEX ) {
127+ continue ;
128+ }
129+
130+ List <Integer > slotNums = getAssignedSlotArray (slotInfo );
131+
132+ // hostInfos
133+ List <Object > hostInfos = (List <Object >) slotInfo .get (MASTER_NODE_INDEX );
134+ if (hostInfos .isEmpty ()) {
135+ continue ;
136+ }
137+
138+ // at this time, we just use master, discard slave information
139+ HostAndPort targetNode = generateHostAndPort (hostInfos );
140+ assignSlotsToNode (slotNums , targetNode );
141+ }
142+ }
143+
121144 private HostAndPort generateHostAndPort (List <Object > hostInfos ) {
122145 return new HostAndPort (SafeEncoder .encode ((byte []) hostInfos .get (0 )),
123146 ((Long ) hostInfos .get (1 )).intValue ());
@@ -222,6 +245,17 @@ public Map<String, JedisPool> getNodes() {
222245 }
223246 }
224247
248+ public List <JedisPool > getShuffledNodesPool () {
249+ r .lock ();
250+ try {
251+ List <JedisPool > pools = new ArrayList <JedisPool >(nodes .values ());
252+ Collections .shuffle (pools );
253+ return pools ;
254+ } finally {
255+ r .unlock ();
256+ }
257+ }
258+
225259 /**
226260 * Clear discovered nodes collections and gently release allocated resources
227261 */
@@ -264,5 +298,4 @@ private List<Integer> getAssignedSlotArray(List<Object> slotInfo) {
264298 }
265299 return slotNums ;
266300 }
267-
268301}
0 commit comments