private void checkSlotsMigration(Collection<ClusterPartition> newPartitions) { List<ClusterPartition> currentPartitions = new ArrayList<ClusterPartition>(lastPartitions.values()); for (ClusterPartition currentPartition : currentPartitions) { for (ClusterPartition newPartition : newPartitions) { if (!currentPartition.getNodeId().equals(newPartition.getNodeId())) { continue; } Set<ClusterSlotRange> addedSlots = new HashSet<ClusterSlotRange>(newPartition.getSlotRanges()); addedSlots.removeAll(currentPartition.getSlotRanges()); MasterSlaveEntry entry = getEntry(currentPartition.getSlotRanges().iterator().next()); currentPartition.addSlotRanges(addedSlots); for (ClusterSlotRange slot : addedSlots) { entry.addSlotRange(slot); addEntry(slot, entry); log.info("{} slot added for {}", slot, entry.getClient().getAddr()); lastPartitions.put(slot, currentPartition); } Set<ClusterSlotRange> removedSlots = new HashSet<ClusterSlotRange>(currentPartition.getSlotRanges()); removedSlots.removeAll(newPartition.getSlotRanges()); lastPartitions.keySet().removeAll(removedSlots); currentPartition.removeSlotRanges(removedSlots); for (ClusterSlotRange slot : removedSlots) { log.info("{} slot removed for {}", slot, entry.getClient().getAddr()); entry.removeSlotRange(slot); removeMaster(slot); } } } }
private void addRemoveSlaves( final MasterSlaveEntry entry, final ClusterPartition currentPart, final ClusterPartition newPart) { Set<URI> removedSlaves = new HashSet<URI>(currentPart.getSlaveAddresses()); removedSlaves.removeAll(newPart.getSlaveAddresses()); for (URI uri : removedSlaves) { currentPart.removeSlaveAddress(uri); slaveDown(entry, uri.getHost(), uri.getPort(), FreezeReason.MANAGER); log.info("slave {} removed for slot ranges: {}", uri, currentPart.getSlotRanges()); } Set<URI> addedSlaves = new HashSet<URI>(newPart.getSlaveAddresses()); addedSlaves.removeAll(currentPart.getSlaveAddresses()); for (final URI uri : addedSlaves) { Future<Void> future = entry.addSlave(uri.getHost(), uri.getPort()); future.addListener( new FutureListener<Void>() { @Override public void operationComplete(Future<Void> future) throws Exception { if (!future.isSuccess()) { log.error("Can't add slave: " + uri, future.cause()); return; } currentPart.addSlaveAddress(uri); entry.slaveUp(uri.getHost(), uri.getPort(), FreezeReason.MANAGER); log.info("slave {} added for slot ranges: {}", uri, currentPart.getSlotRanges()); } }); } }
private void checkSlotsChange( ClusterServersConfig cfg, Collection<ClusterPartition> newPartitions) { checkSlotsMigration(newPartitions); Collection<ClusterSlotRange> newPartitionsSlots = slots(newPartitions); Set<ClusterSlotRange> removedSlots = new HashSet<ClusterSlotRange>(lastPartitions.keySet()); removedSlots.removeAll(newPartitionsSlots); lastPartitions.keySet().removeAll(removedSlots); if (!removedSlots.isEmpty()) { log.info("{} slot ranges found to remove", removedSlots); } for (ClusterSlotRange slot : removedSlots) { MasterSlaveEntry entry = removeMaster(slot); entry.removeSlotRange(slot); if (entry.getSlotRanges().isEmpty()) { entry.shutdownMasterAsync(); log.info("{} master and slaves for it removed", entry.getClient().getAddr()); } } Set<ClusterSlotRange> addedSlots = new HashSet<ClusterSlotRange>(newPartitionsSlots); addedSlots.removeAll(lastPartitions.keySet()); if (!addedSlots.isEmpty()) { log.info("{} slots found to add", addedSlots); } for (final ClusterSlotRange slot : addedSlots) { ClusterPartition partition = find(newPartitions, slot); boolean masterFound = false; for (MasterSlaveEntry entry : getEntries().values()) { if (entry.getClient().getAddr().equals(partition.getMasterAddr())) { addEntry(slot, entry); lastPartitions.put(slot, partition); masterFound = true; break; } } if (!masterFound) { Future<Collection<Future<Void>>> future = addMasterEntry(partition, cfg); future.addListener( new FutureListener<Collection<Future<Void>>>() { @Override public void operationComplete(Future<Collection<Future<Void>>> future) throws Exception { if (!future.isSuccess()) { log.error( "New cluster slot range " + slot + " without master node detected", future.cause()); } } }); } } }
private void upDownSlaves( final MasterSlaveEntry entry, final ClusterPartition currentPart, final ClusterPartition newPart) { Set<URI> aliveSlaves = new HashSet<URI>(currentPart.getFailedSlaveAddresses()); aliveSlaves.removeAll(newPart.getFailedSlaveAddresses()); for (URI uri : aliveSlaves) { currentPart.removeFailedSlaveAddress(uri); if (entry.slaveUp(uri.getHost(), uri.getPort(), FreezeReason.MANAGER)) { log.info("slave: {} has up for slot ranges: {}", uri, currentPart.getSlotRanges()); } } Set<URI> failedSlaves = new HashSet<URI>(newPart.getFailedSlaveAddresses()); failedSlaves.removeAll(currentPart.getFailedSlaveAddresses()); for (URI uri : failedSlaves) { currentPart.addFailedSlaveAddress(uri); slaveDown(entry, uri.getHost(), uri.getPort(), FreezeReason.MANAGER); log.warn("slave: {} has down for slot ranges: {}", uri, currentPart.getSlotRanges()); } }
private void checkForReconnect(ClientConnectionsEntry entry) { if (entry.getNodeType() == NodeType.SLAVE) { masterSlaveEntry.slaveDown( entry.getClient().getAddr().getHostName(), entry.getClient().getAddr().getPort(), FreezeReason.RECONNECT); log.warn( "slave {} disconnected due to failedAttempts={} limit reached", entry.getClient().getAddr(), config.getFailedAttempts()); scheduleCheck(entry); } else { if (entry.freezeMaster(FreezeReason.RECONNECT)) { log.warn( "host {} disconnected due to failedAttempts={} limit reached", entry.getClient().getAddr(), config.getFailedAttempts()); scheduleCheck(entry); } } }
public Future<T> get() { for (int j = entries.size() - 1; j >= 0; j--) { ClientConnectionsEntry entry = getEntry(); if (!entry.isFreezed() && tryAcquireConnection(entry)) { return connectTo(entry); } } List<InetSocketAddress> zeroConnectionsAmount = new LinkedList<InetSocketAddress>(); List<InetSocketAddress> freezed = new LinkedList<InetSocketAddress>(); for (ClientConnectionsEntry entry : entries) { if (entry.isFreezed()) { freezed.add(entry.getClient().getAddr()); } else { zeroConnectionsAmount.add(entry.getClient().getAddr()); } } StringBuilder errorMsg; if (connectionManager.isClusterMode()) { errorMsg = new StringBuilder( "Connection pool exhausted! for slots: " + masterSlaveEntry.getSlotRanges()); } else { errorMsg = new StringBuilder("Connection pool exhausted! "); } if (!freezed.isEmpty()) { errorMsg.append(" Disconnected hosts: " + freezed); } if (!zeroConnectionsAmount.isEmpty()) { errorMsg.append(" Hosts with fully busy connections: " + zeroConnectionsAmount); } RedisConnectionException exception = new RedisConnectionException(errorMsg.toString()); return connectionManager.newFailedFuture(exception); }