Jedis 4.4.3 JedisCluster通过key获得哈希槽,再通过哈希槽得到节点的连接的源码

  • Post author:
  • Post category:其他


了解完redis服务端,就有一个疑问,如果redis是集群模式,客户端通过什么方式知道我要请求哪个节点呢?

下面就通过源码解析一下



1、拿set和get举例子

示例是从https://www.cnblogs.com/c-xiaohai/p/8376364.html 这里抄的

public static void main(String[] args) {
        // 添加集群的服务节点Set集合
        Set<HostAndPort> hostAndPortsSet = new HashSet<HostAndPort>();
        // 添加节点
        hostAndPortsSet.add(new HostAndPort("192.168.56.180", 7777));
        hostAndPortsSet.add(new HostAndPort("192.168.56.180", 8888));
        hostAndPortsSet.add(new HostAndPort("192.168.56.181", 7777));
        hostAndPortsSet.add(new HostAndPort("192.168.56.181", 8888));
        hostAndPortsSet.add(new HostAndPort("192.168.56.182", 7777));
        hostAndPortsSet.add(new HostAndPort("192.168.56.182", 8888));

        // Jedis连接池配置
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大空闲连接数, 默认8个
        jedisPoolConfig.setMaxIdle(100);
        // 最大连接数, 默认8个
        jedisPoolConfig.setMaxTotal(500);
        //最小空闲连接数, 默认0
        jedisPoolConfig.setMinIdle(0);
        // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
        jedisPoolConfig.setMaxWaitMillis(2000); // 设置2秒
        //对拿到的connection进行validateObject校验
        jedisPoolConfig.setTestOnBorrow(true);
        JedisCluster jedisCluster = new JedisCluster(hostAndPortsSet, jedisPoolConfig);


        jedisCluster.set("key", "value");
        jedisCluster.get("key");

    }



2、通过key计算哈希槽,再通过哈希槽得到槽所在节点的连接

 public String set(String key, String value) {
        return (String)this.executeCommand(this.commandObjects.set(key, value));
    }
  public String get(String key) {
        return (String)this.executeCommand(this.commandObjects.get(key));
    }
   
  public final <T> T executeCommand(CommandObject<T> commandObject) {
        return this.executor.executeCommand(commandObject);
    }   
 public final <T> T executeCommand(CommandObject<T> commandObject) {
       //省略。。。。
       JedisRedirectionException redirect = null;
      if (redirect != null) { //这个可以忽略
          connection = this.provider.getConnection(redirect.getTargetNode());
          if (redirect instanceof JedisAskDataException) {
               connection.executeCommand(Command.ASKING);
            }
       } else {
       //这个是获取连接的命令,通过入参调用getConnection得到连接
          connection = this.provider.getConnection(commandObject.getArguments());
       }
       Object var8 = this.execute(connection, commandObject);
       return var8;
    //省略。。。。
    }

下面是

getConnection

方法的实现,实际上是通过入参得到哈希槽,再通过哈希槽得到此哈希槽所在节点的连接

 public Connection getConnection(CommandArguments args) {
        int slot = ((ClusterCommandArguments)args).getCommandHashSlot();
        return slot >= 0 ? this.getConnectionFromSlot(slot) : this.getConnection();
    }



版权声明:本文为weixin_43113679原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。