美文网首页Redis大数据开发
大数据开发:Redis Cluster模式连接原理

大数据开发:Redis Cluster模式连接原理

作者: 成都加米谷大数据 | 来源:发表于2021-07-19 17:51 被阅读0次

在Redis 3.0 之后,引入了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模式连接原理,以上就为大家做了具体的操作讲解了,也结合到代码进行了展示,大家可以多理解理解。

相关文章

网友评论

    本文标题:大数据开发:Redis Cluster模式连接原理

    本文链接:https://www.haomeiwen.com/subject/myyhmltx.html