Refine search
@Override public void clusterMeet(RedisClusterNode node) { Assert.notNull(node, "Cluster node must not be null for CLUSTER MEET command!"); Assert.hasText(node.getHost(), "Node to meet cluster must have a host!"); Assert.isTrue(node.getPort() > 0, "Node to meet cluster must have a port greater 0!"); RFuture<Void> f = executorService.writeAsync((String)null, StringCodec.INSTANCE, RedisCommands.CLUSTER_MEET, node.getHost(), node.getPort()); syncFuture(f); }
@Override public Set<RedisClusterNode> clusterGetSlaves(RedisClusterNode master) { Assert.notNull(master, "Master cannot be null!"); RedisClusterNode nodeToUse = topologyProvider.getTopology().lookup(master); return JedisConverters.toSetOfRedisClusterNodes(clusterCommandExecutor .executeCommandOnSingleNode( (JedisClusterCommandCallback<List<String>>) client -> client.clusterSlaves(nodeToUse.getId()), master) .getValue()); }
/** * Get the {@link RedisClusterNode} that is the current master serving the given key. * * @param key must not be {@literal null}. * @return never {@literal null}. * @throws ClusterStateFailureException */ public RedisClusterNode getKeyServingMasterNode(byte[] key) { Assert.notNull(key, "Key for node lookup must not be null!"); int slot = ClusterSlotHashUtil.calculateSlot(key); for (RedisClusterNode node : nodes) { if (node.isMaster() && node.servesSlot(slot)) { return node; } } throw new ClusterStateFailureException( String.format("Could not find master node serving slot %s for key '%s',", slot, Arrays.toString(key))); }
@Override public Collection<RedisClusterNode> clusterGetSlaves(RedisClusterNode master) { Iterable<RedisClusterNode> res = clusterGetNodes(); RedisClusterNode masterNode = null; for (Iterator<RedisClusterNode> iterator = res.iterator(); iterator.hasNext();) { RedisClusterNode redisClusterNode = iterator.next(); if (master.getHost().equals(redisClusterNode.getHost()) && master.getPort().equals(redisClusterNode.getPort())) { masterNode = redisClusterNode; break; } } if (masterNode == null) { throw new IllegalStateException("Unable to find master node: " + master); } for (Iterator<RedisClusterNode> iterator = res.iterator(); iterator.hasNext();) { RedisClusterNode redisClusterNode = iterator.next(); if (redisClusterNode.getMasterId() == null || !redisClusterNode.getMasterId().equals(masterNode.getId())) { iterator.remove(); } } return (Collection<RedisClusterNode>) res; }
@Override public RedisClusterNode clusterGetNodeForSlot(int slot) { Iterable<RedisClusterNode> res = clusterGetNodes(); for (RedisClusterNode redisClusterNode : res) { if (redisClusterNode.isMaster() && redisClusterNode.getSlotRange().contains(slot)) { return redisClusterNode; } } return null; }
@Override public Properties info(String section) { Assert.notNull(section, "Section must not be null!"); Properties infos = new Properties(); List<NodeResult<Properties>> nodeResults = connection.getClusterCommandExecutor() .executeCommandOnAllNodes( (JedisClusterCommandCallback<Properties>) client -> JedisConverters.toProperties(client.info(section))) .getResults(); for (NodeResult<Properties> nodeProperties : nodeResults) { for (Entry<Object, Object> entry : nodeProperties.getValue().entrySet()) { infos.put(nodeProperties.getNode().asString() + "." + entry.getKey(), entry.getValue()); } } return infos; }
@Override public RedisClusterNode convert(String source) { String[] args = source.split(" "); String[] hostAndPort = StringUtils.split(args[HOST_PORT_INDEX], ":"); Assert.notNull(hostAndPort, "CusterNode information does not define host and port!"); SlotRange range = parseSlotRange(args); Set<Flag> flags = parseFlags(args); String portPart = hostAndPort[1]; if (portPart.contains("@")) { portPart = portPart.substring(0, portPart.indexOf('@')); } RedisClusterNodeBuilder nodeBuilder = RedisClusterNode.newRedisClusterNode() .listeningAt(hostAndPort[0], Integer.valueOf(portPart)) // .withId(args[ID_INDEX]) // .promotedAs(flags.contains(Flag.MASTER) ? NodeType.MASTER : NodeType.SLAVE) // .serving(range) // .withFlags(flags) // .linkState(parseLinkState(args)); if (!args[MASTER_ID_INDEX].isEmpty() && !args[MASTER_ID_INDEX].startsWith("-")) { nodeBuilder.slaveOf(args[MASTER_ID_INDEX]); } return nodeBuilder.build(); }
/** * Get the {@link RedisClusterNode} matching matching either {@link RedisClusterNode#getHost() host} and * {@link RedisClusterNode#getPort() port} or {@link RedisClusterNode#getId() nodeId} * * @param node must not be {@literal null} * @return never {@literal null}. * @throws ClusterStateFailureException */ public RedisClusterNode lookup(RedisClusterNode node) { Assert.notNull(node, "RedisClusterNode must not be null!"); if (nodes.contains(node) && StringUtils.hasText(node.getHost()) && StringUtils.hasText(node.getId())) { return node; } if (StringUtils.hasText(node.getHost()) && node.getPort() != null) { return lookup(node.getHost(), node.getPort()); } if (StringUtils.hasText(node.getId())) { return lookup(node.getId()); } throw new ClusterStateFailureException( String.format("Could not find node at %s. Have you provided either host and port or the nodeId?", node)); }
/** * Get the {@link RedisClusterNode} matching given {@literal nodeId}. * * @param nodeId must not be {@literal null}. * @return never {@literal null}. * @throws ClusterStateFailureException */ public RedisClusterNode lookup(String nodeId) { Assert.notNull(nodeId, "NodeId must not be null!"); for (RedisClusterNode node : nodes) { if (nodeId.equals(node.getId())) { return node; } } throw new ClusterStateFailureException( String.format("Could not find node at %s. Is your cluster info up to date?", nodeId)); }
@Override @SuppressWarnings("unchecked") public RedisClusterCommands<byte[], byte[]> getResourceForSpecificNode(RedisClusterNode node) { Assert.notNull(node, "Node must not be null!"); if (connection == null) { synchronized (this) { if (connection == null) { this.connection = connectionProvider.getConnection(StatefulRedisClusterConnection.class); } } } try { return connection.getConnection(node.getHost(), node.getPort()).sync(); } catch (RedisException e) { throw new DataAccessResourceFailureException(e.getMessage(), e); } }
@Override public Properties info(String section) { Assert.hasText(section, "Section must not be null or empty!"); Properties infos = new Properties(); List<NodeResult<Properties>> nodeResults = executeCommandOnAllNodes( client -> LettuceConverters.toProperties(client.info(section))).getResults(); for (NodeResult<Properties> nodePorperties : nodeResults) { for (Entry<Object, Object> entry : nodePorperties.getValue().entrySet()) { infos.put(nodePorperties.getNode().asString() + "." + entry.getKey(), entry.getValue()); } } return infos; }
@Override public Map<RedisClusterNode, Collection<RedisClusterNode>> clusterGetMasterSlaveMap() { Iterable<RedisClusterNode> res = clusterGetNodes(); Set<RedisClusterNode> masters = new HashSet<RedisClusterNode>(); for (Iterator<RedisClusterNode> iterator = res.iterator(); iterator.hasNext();) { RedisClusterNode redisClusterNode = iterator.next(); if (redisClusterNode.isMaster()) { masters.add(redisClusterNode); } } Map<RedisClusterNode, Collection<RedisClusterNode>> result = new HashMap<RedisClusterNode, Collection<RedisClusterNode>>(); for (Iterator<RedisClusterNode> iterator = res.iterator(); iterator.hasNext();) { RedisClusterNode redisClusterNode = iterator.next(); for (RedisClusterNode masterNode : masters) { if (redisClusterNode.getMasterId() != null && redisClusterNode.getMasterId().equals(masterNode.getId())) { Collection<RedisClusterNode> list = result.get(masterNode); if (list == null) { list = new ArrayList<RedisClusterNode>(); result.put(masterNode, list); } list.add(redisClusterNode); } } } return result; }
/** * Run {@link MultiKeyClusterCommandCallback} with on a curated set of nodes serving one or more keys. * * @param cmd must not be {@literal null}. * @return never {@literal null}. * @throws ClusterCommandExecutionFailureException */ public <S, T> MultiNodeResult<T> executeMultiKeyCommand(MultiKeyClusterCommandCallback<S, T> cmd, Iterable<byte[]> keys) { Map<RedisClusterNode, PositionalKeys> nodeKeyMap = new HashMap<>(); int index = 0; for (byte[] key : keys) { for (RedisClusterNode node : getClusterTopology().getKeyServingNodes(key)) { nodeKeyMap.computeIfAbsent(node, val -> PositionalKeys.empty()).append(PositionalKey.of(key, index++)); } } Map<NodeExecution, Future<NodeResult<T>>> futures = new LinkedHashMap<>(); for (Entry<RedisClusterNode, PositionalKeys> entry : nodeKeyMap.entrySet()) { if (entry.getKey().isMaster()) { for (PositionalKey key : entry.getValue()) { futures.put(new NodeExecution(entry.getKey(), key), executor.submit(() -> executeMultiKeyCommandOnSingleNode(cmd, entry.getKey(), key.getBytes()))); } } } return collectResults(futures); }
@Override public void clusterReplicate(RedisClusterNode master, RedisClusterNode replica) { RedisClusterNode masterNode = topologyProvider.getTopology().lookup(master); clusterCommandExecutor.executeCommandOnSingleNode( (LettuceClusterCommandCallback<String>) client -> client.clusterReplicate(masterNode.getId()), replica); }
private Jedis getConnectionForSpecificNode(RedisClusterNode node) { RedisClusterNode member = topologyProvider.getTopology().lookup(node); if (member != null && connectionHandler != null) { return connectionHandler.getConnectionFromNode(new HostAndPort(member.getHost(), member.getPort())); } return null; }
/** * Get all master nodes in cluster where {@code link-state} is {@literal connected} and {@code flags} does not contain * {@literal fail} or {@literal fail?}. * * @return never {@literal null}. */ public Set<RedisClusterNode> getActiveMasterNodes() { Set<RedisClusterNode> activeMasterNodes = new LinkedHashSet<>(nodes.size()); for (RedisClusterNode node : nodes) { if (node.isMaster() && node.isConnected() && !node.isMarkedAsFail()) { activeMasterNodes.add(node); } } return activeMasterNodes; }
@Override public void clusterForget(RedisClusterNode node) { Set<RedisClusterNode> nodes = new LinkedHashSet<>(topologyProvider.getTopology().getActiveMasterNodes()); RedisClusterNode nodeToRemove = topologyProvider.getTopology().lookup(node); nodes.remove(nodeToRemove); clusterCommandExecutor.executeCommandAsyncOnNodes( (JedisClusterCommandCallback<String>) client -> client.clusterForget(node.getId()), nodes); }
@Override public void clusterForget(RedisClusterNode node) { List<RedisClusterNode> nodes = new ArrayList<>(clusterGetNodes()); RedisClusterNode nodeToRemove = topologyProvider.getTopology().lookup(node); nodes.remove(nodeToRemove); this.clusterCommandExecutor.executeCommandAsyncOnNodes( (LettuceClusterCommandCallback<String>) client -> client.clusterForget(nodeToRemove.getId()), nodes); }
@Override public void clusterForget(RedisClusterNode node) { RFuture<Void> f = executorService.writeAsync((String)null, StringCodec.INSTANCE, RedisCommands.CLUSTER_FORGET, node.getId()); syncFuture(f); }