【redis】【17】JedisCluster的底层存储

JedisCluster有个成员变量JedisClusterConnectionHandler

JedisClusterConnectionHandler中有个成员变量JedisClusterInfoCache

JedisClusterInfoCache中有两个map,一个是nodesMap,一个是soltsMap

一个nodeMap中包含一个JedisPool连接池

一个soltMap中引用对用node的连接池

1.初始化JedisCluster

public JedisCluster(Set<HostAndPort> jedisClusterNode, int timeout, int maxRedirections,
      final GenericObjectPoolConfig poolConfig) {
    super(jedisClusterNode, timeout, maxRedirections, poolConfig);
  }

1.1参数一:主机节点集合

//redis.cluster.ip=192.168.204.125:7114,192.168.204.125:7115,192.168.204.125:7116,
//192.168.204.125:7111,192.168.204.125:7112,192.168.204.125:7113
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>(); 
String[] redisIps = redisIp.split(",");
for(String redisIpStr:redisIps) {
	jedisClusterNodes.add(new HostAndPort(redisIpStr.split(":")[0],
	Integer.parseInt(redisIpStr.split(":")[1])));
}
					}

1.2GenericObjectPoolConfig 连接池配置

https://blog.csdn.net/huiyanshizhen21/article/details/107872435

JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(100);   
config.setMaxIdle(50);   
config.setMinIdle(20);   
config.setMaxWaitMillis(6 * 1000);   
config.setTestOnBorrow(true);
int timeout = 2000;
int maxRedirections = 6;

1.3初始化

jedisCluster = new JedisCluster(jedisClusterNodes, timeout, maxRedirections, config);	

2.JedisCluster父类BinaryJedisCluster初始化

public class BinaryJedisCluster implements BasicCommands, BinaryJedisClusterCommands,
    MultiKeyBinaryJedisClusterCommands, JedisClusterBinaryScriptingCommands, Closeable {
	
	public static final short HASHSLOTS = 16384;
    protected static final int DEFAULT_TIMEOUT = 2000;
    protected static final int DEFAULT_MAX_REDIRECTIONS = 5;
    protected int maxRedirections;
	protected JedisClusterConnectionHandler connectionHandler;
	
	public BinaryJedisCluster(Set<HostAndPort> jedisClusterNode, int timeout, int maxRedirections,
		  final GenericObjectPoolConfig poolConfig) {
		this.connectionHandler = new JedisSlotBasedConnectionHandler(jedisClusterNode, poolConfig,
			timeout);
		this.maxRedirections = maxRedirections;
	}	

}

3.初始化BinaryJedisCluster类的成员变量

public class JedisSlotBasedConnectionHandler extends JedisClusterConnectionHandler {

  public JedisSlotBasedConnectionHandler(Set<HostAndPort> nodes,
      final GenericObjectPoolConfig poolConfig, int timeout) {
    this(nodes, poolConfig, timeout, timeout);
  }
}

4.初始化BinaryJedisCluster类的父类

public abstract class JedisClusterConnectionHandler {
  protected final JedisClusterInfoCache cache;

  public JedisClusterConnectionHandler(Set<HostAndPort> nodes,
                                       final GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout) {
    this.cache = new JedisClusterInfoCache(poolConfig, connectionTimeout, soTimeout);
    initializeSlotsCache(nodes, poolConfig);
  }
  
  private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig) {
    for (HostAndPort hostAndPort : startNodes) {
      Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());
      try {
        cache.discoverClusterNodesAndSlots(jedis);
        break;
      } catch (JedisConnectionException e) {
        // try next nodes
      } finally {
        if (jedis != null) {
          jedis.close();
        }
      }
    }

    for (HostAndPort node : startNodes) {
      cache.setNodeIfNotExist(node);
    }
  }
}  

5.初始化BinaryJedisCluster类的成员变量JedisClusterInfoCache

public class JedisClusterInfoCache {
  private Map<String, JedisPool> nodes = new HashMap<String, JedisPool>();
  private Map<Integer, JedisPool> slots = new HashMap<Integer, JedisPool>();

  private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  private final Lock r = rwl.readLock();
  private final Lock w = rwl.writeLock();
  private final GenericObjectPoolConfig poolConfig;

  private int connectionTimeout;
  private int soTimeout;

  private static final int MASTER_NODE_INDEX = 2;

  public void discoverClusterNodesAndSlots(Jedis jedis) {
    w.lock();

    try {
      this.nodes.clear();
      this.slots.clear();

      List<Object> slots = jedis.clusterSlots();

      for (Object slotInfoObj : slots) {
        List<Object> slotInfo = (List<Object>) slotInfoObj;

        if (slotInfo.size() <= MASTER_NODE_INDEX) {
          continue;
        }

        List<Integer> slotNums = getAssignedSlotArray(slotInfo);

        // hostInfos
        int size = slotInfo.size();
        for (int i = MASTER_NODE_INDEX; i < size; i++) {
          List<Object> hostInfos = (List<Object>) slotInfo.get(i);
          if (hostInfos.size() <= 0) {
            continue;
          }

          HostAndPort targetNode = generateHostAndPort(hostInfos);
          setNodeIfNotExist(targetNode);
          if (i == MASTER_NODE_INDEX) {
            assignSlotsToNode(slotNums, targetNode);
          }
        }
      }
    } finally {
      w.unlock();
    }
  }
  public void setNodeIfNotExist(HostAndPort node) {
    w.lock();
    try {
      String nodeKey = getNodeKey(node);
      if (nodes.containsKey(nodeKey)) return;

      JedisPool nodePool = new JedisPool(poolConfig, node.getHost(), node.getPort(),
              connectionTimeout, soTimeout, null, 0, null);
      nodes.put(nodeKey, nodePool);
    } finally {
      w.unlock();
    }
  } 
}

你可能感兴趣的:(redis)