主页 > 新闻资讯 > 大数据学习:Redis Cluster模式连接原理

大数据学习:Redis Cluster模式连接原理

作者:张老师 浏览次数: 2021-06-25 16:40
在Redis 3.0 之后,引入了Cluster模式,对于集群模式下的相关操作,也是需要大家在学习当中去逐步掌握的。今天的大数据学习分享,我们就主要来讲讲Redis Cluster模式连接原理。

大数据学习:Redis Cluster模式连接原理

这里主要以jedis客户端为例,说明在redis cluster模式中客户端应当如何去连接redis服务端。

一般在配置redis连接时伪代码大致如下,在对JedisCluster进行初始化时代码最终会调到discoverClusterNodesAndSlots方法中,在初始化时会将slot与jedisPool进行映射。

        Set<HostAndPort> sets = new HashSet<>();
        sets.add(new HostAndPort("ip",6379));
        sets.add(new HostAndPort("ip2",6380));

        JedisCluster jedisCluster = new JedisCluster(sets);
        jedisCluster.set("key","value");

其实可以看出无论配置了几台机器的ip最终只会用一台获取服务端node与槽信息,那么在往redis里存数据时是如何知道该往那个节点上存?

  private void initializeSlotsCache(Set<HostAndPort> startNodes, GenericObjectPoolConfig poolConfig, String password) {
    for (HostAndPort hostAndPort : startNodes) {
      Jedis jedis = new Jedis(hostAndPort.getHost(), hostAndPort.getPort());
      if (password != null) {
        jedis.auth(password);
      }
      try {
        cache.discoverClusterNodesAndSlots(jedis);
        break;
      } catch (JedisConnectionException e) {
        // try next nodes
      } finally {
        if (jedis != null) {
          jedis.close();
        }
      }
    }
  }

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

    try {
      reset();
      //获取服务端所有节点的槽信息
      //{[0,5460, 6378, 6379],[5461,10922,6380,6381],[10923,16383,6382,6383]}
      List<Object> slots = jedis.clusterSlots();

      for (Object slotInfoObj : slots) {
                   //槽信息 //主端口 //从端口
        //slotInfo [0, 5460, 6378, 6379]
        List<Object> slotInfo = (List<Object>) slotInfoObj;
        //小于等于2表示没有分配slot
        if (slotInfo.size() <= MASTER_NODE_INDEX) {
          continue;
        }
        //获取分配到当前master节点的数据槽 例如6378节点 {0,1,2,3...5460}
        List<Integer> slotNums = getAssignedSlotArray(slotInfo);

        // hostInfos
        int size = slotInfo.size();
        //遍历第3位第4位主从端口信息
        for (int i = MASTER_NODE_INDEX; i < size; i++) {
          List<Object> hostInfos = (List<Object>) slotInfo.get(i);
          if (hostInfos.size() <= 0) {
            continue;
          }
          //根据IP端口生成HostAndPort实例
          HostAndPort targetNode = generateHostAndPort(hostInfos);
          //将解析出来的ip:port作为,并从缓存中获取JedisPool,如果没有JedisPool则会构建
          //JedisPool并放入缓存中,缓存中存放nodeKey与JedisPool的关系
          setupNodeIfNotExist(targetNode);
          if (i == MASTER_NODE_INDEX) {
            //将slot与JedisPool缓存起来(16384个),key为slot,value为JedisPool
            assignSlotsToNode(slotNums, targetNode);
          }
        }
      }
    } finally {
      w.unlock();
    }
  }

当通过key进行操作redis时则首先通过key用CRC16算法进行计算,然后再%16384,这时会得到一个余数,也就是该key计算得到的slot,再通过该slot从缓存中获取JedisPool

        JedisCluster jedisCluster = new JedisCluster();
        jedisCluster.set("123","");

set方法最终会调到下面方面里面,可以看出是通过slot首先获取到初始化时映射好的jedisPool

    public Jedis getConnectionFromSlot(int slot) {
    JedisPool connectionPool = cache.getSlotPool(slot);
    if (connectionPool != null) {
      // It can't guaranteed to get valid connection because of node
      // assignment
      return connectionPool.getResource();
    } else {
      renewSlotCache(); //It's abnormal situation for cluster mode, that we have just nothing for slot, try to rediscover state
      connectionPool = cache.getSlotPool(slot);
      if (connectionPool != null) {
        return connectionPool.getResource();
      } else {
        //no choice, fallback to new connection to random node
        return getConnection();
      }
    }
  }

关于大数据学习,Redis Cluster模式连接原理,以上就为大家做了具体的操作讲解了,也结合到代码进行了展示,大家可以多理解理解。成都加米谷大数据,专业大数据培训,大数据开发、数据分析与挖掘,零基础班本月正在招生中,课程大纲及试学视频,可联系客服获取!
热点排行
推荐文章
立即申请>>