zoukankan      html  css  js  c++  java
  • redis集群JedisCluster连接关闭问题

    JedisCluster连接关闭问题

    set方法为例

    //伪代码
    JedisCluster jedisCluster = new JedisCluster();
    jedisCluster.set("testKey", "testValue");
    

    进入到set方法

    • 类JedisCluster中;

    • 初始化一个JedisClusterCommand对象,调用run方法;

    • 需要实现一个execute方法,通过Jedis调用set方法(这里又回到单节点调用set的方式了);

    public String set(final String key, final String value) {
       return new JedisClusterCommand<String>(connectionHandler, maxAttempts) {
         @Override
         public String execute(Jedis connection) {
           return connection.set(key, value);
         }
       }.run(key);
     }
    

    进入到run方法

    • 类JedisClusterCommand中;
    public T run(String key) {
       return runWithRetries(JedisClusterCRC16.getSlot(key), this.maxAttempts, false, null);
     }
    

    进入到runWithRetries方法

    • 类JedisClusterCommand中;
    • 只需要关注2个地方即可;
      • return execute(connection),这里调用了之前实现的execute方法;
      • releaseConnection(connection),在finally中释放了连接;
    private T runWithRetries(final int slot, int attempts, boolean tryRandomNode, JedisRedirectionException redirect) {
        if (attempts <= 0) {
          throw new JedisClusterMaxAttemptsException("No more cluster attempts left.");
        }
    
        Jedis connection = null;
        try {
    		//此处为空,走else
          if (redirect != null) {
            connection = this.connectionHandler.getConnectionFromNode(redirect.getTargetNode());
            if (redirect instanceof JedisAskDataException) {
              // TODO: Pipeline asking with the original command to make it faster....
              connection.asking();
            }
          } else {
            //此处是false,走else
            if (tryRandomNode) {
              connection = connectionHandler.getConnection();
            } else {
              //这里会从池中获取一个Jedis对象
              connection = connectionHandler.getConnectionFromSlot(slot);
            }
          }
    		//这里调用最开始实现的execute方法
          return execute(connection);
    
        } catch (JedisNoReachableClusterNodeException jnrcne) {
          throw jnrcne;
        } catch (JedisConnectionException jce) {
          // release current connection before recursion
          releaseConnection(connection);
          connection = null;
    
          if (attempts <= 1) {
            //We need this because if node is not reachable anymore - we need to finally initiate slots
            //renewing, or we can stuck with cluster state without one node in opposite case.
            //But now if maxAttempts = [1 or 2] we will do it too often.
            //TODO make tracking of successful/unsuccessful operations for node - do renewing only
            //if there were no successful responses from this node last few seconds
            this.connectionHandler.renewSlotCache();
          }
    
          return runWithRetries(slot, attempts - 1, tryRandomNode, redirect);
        } catch (JedisRedirectionException jre) {
          // if MOVED redirection occurred,
          if (jre instanceof JedisMovedDataException) {
            // it rebuilds cluster's slot cache recommended by Redis cluster specification
            this.connectionHandler.renewSlotCache(connection);
          }
    
          // release current connection before recursion
          releaseConnection(connection);
          connection = null;
    
          return runWithRetries(slot, attempts - 1, false, jre);
        } finally {
          //此处释放了连接
          releaseConnection(connection);
        }
      }
    
    

    进入到releaseConnection方法

    • 类JedisClusterCommand中;
    • 实际上是通过Jedis.close()关闭的,和我们用单节点时,是一样的关闭方式;
    private void releaseConnection(Jedis connection) {
        if (connection != null) {
          connection.close();
        }
      }
    

    总结

    • 使用JedisCluster时,不需要手动释放连接;
    • 在调用的过程中,会自动释放连接;
    • 实际上是JedisCluster中通过JedisPool获取Jedis来执行命令;
  • 相关阅读:
    POJ 1979 Red and Black
    MyEclipse7.0破解下载
    【android开发】Android防止内存溢出浅析
    数据库索引的作用和长处缺点
    怎样基于android4.4.2的源代码和android-4.3.1_r1的驱动编译I9250的ROM
    Eclipse中SVN的安装步骤(两种)和用法
    又拍云服务评測分享
    Objective-C语法之代码块(block)的使用
    《linux 内核全然剖析》 chapter 2 微型计算机组成结构
    浅谈UML的概念和模型之UML九种图
  • 原文地址:https://www.cnblogs.com/xiaodf/p/12167268.html
Copyright © 2011-2022 走看看