Search in sources :

Example 6 with OptimizationOptions

use of com.linkedin.kafka.cruisecontrol.analyzer.OptimizationOptions in project cruise-control by linkedin.

the class TopicReplicaDistributionGoal method rebalanceByMovingReplicasOut.

private boolean rebalanceByMovingReplicasOut(Broker broker, String topic, ClusterModel clusterModel, Set<Goal> optimizedGoals, OptimizationOptions optimizationOptions) {
    // Get the eligible brokers.
    SortedSet<Broker> candidateBrokers = new TreeSet<>(Comparator.comparingInt((Broker b) -> b.numReplicasOfTopicInBroker(topic)).thenComparingInt(Broker::id));
    candidateBrokers.addAll(_fixOfflineReplicasOnly ? clusterModel.aliveBrokers() : clusterModel.aliveBrokers().stream().filter(b -> b.numReplicasOfTopicInBroker(topic) < _balanceUpperLimitByTopic.get(topic)).collect(Collectors.toSet()));
    Collection<Replica> replicasOfTopicInBroker = broker.replicasOfTopicInBroker(topic);
    int numReplicasOfTopicInBroker = replicasOfTopicInBroker.size();
    int numOfflineTopicReplicas = GoalUtils.retainCurrentOfflineBrokerReplicas(broker, replicasOfTopicInBroker).size();
    // If the source broker is excluded for replica move, set its upper limit to 0.
    int balanceUpperLimitForSourceBroker = isExcludedForReplicaMove(broker) ? 0 : _balanceUpperLimitByTopic.get(topic);
    boolean wasUnableToMoveOfflineReplica = false;
    for (Replica replica : replicasToMoveOut(broker, topic)) {
        if (wasUnableToMoveOfflineReplica && !replica.isCurrentOffline() && numReplicasOfTopicInBroker <= balanceUpperLimitForSourceBroker) {
            // Was unable to move offline replicas from the broker, and remaining replica count is under the balance limit.
            return false;
        }
        boolean wasOffline = replica.isCurrentOffline();
        Broker b = maybeApplyBalancingAction(clusterModel, replica, candidateBrokers, ActionType.INTER_BROKER_REPLICA_MOVEMENT, optimizedGoals, optimizationOptions);
        // Only check if we successfully moved something.
        if (b != null) {
            if (wasOffline) {
                numOfflineTopicReplicas--;
            }
            if (--numReplicasOfTopicInBroker <= (numOfflineTopicReplicas == 0 ? balanceUpperLimitForSourceBroker : 0)) {
                return false;
            }
            // Remove and reinsert the broker so the order is correct.
            candidateBrokers.remove(b);
            if (b.numReplicasOfTopicInBroker(topic) < _balanceUpperLimitByTopic.get(topic) || _fixOfflineReplicasOnly) {
                candidateBrokers.add(b);
            }
        } else if (wasOffline) {
            wasUnableToMoveOfflineReplica = true;
        }
    }
    // All the topic replicas has been moved away from the broker.
    return !broker.replicasOfTopicInBroker(topic).isEmpty();
}
Also used : Replica(com.linkedin.kafka.cruisecontrol.model.Replica) SortedReplicasHelper(com.linkedin.kafka.cruisecontrol.model.SortedReplicasHelper) OptimizationOptions(com.linkedin.kafka.cruisecontrol.analyzer.OptimizationOptions) SortedSet(java.util.SortedSet) REPLICA_REJECT(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.REPLICA_REJECT) MIN_NUM_VALID_WINDOWS_FOR_SELF_HEALING(com.linkedin.kafka.cruisecontrol.analyzer.goals.GoalUtils.MIN_NUM_VALID_WINDOWS_FOR_SELF_HEALING) PriorityQueue(java.util.PriorityQueue) ClusterModel(com.linkedin.kafka.cruisecontrol.model.ClusterModel) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) OptimizationFailureException(com.linkedin.kafka.cruisecontrol.exception.OptimizationFailureException) Map(java.util.Map) GoalUtils.replicaSortName(com.linkedin.kafka.cruisecontrol.analyzer.goals.GoalUtils.replicaSortName) ActionAcceptance(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance) Logger(org.slf4j.Logger) EPSILON(com.linkedin.kafka.cruisecontrol.analyzer.AnalyzerUtils.EPSILON) BalancingConstraint(com.linkedin.kafka.cruisecontrol.analyzer.BalancingConstraint) Collection(java.util.Collection) Set(java.util.Set) AnalyzerUtils(com.linkedin.kafka.cruisecontrol.analyzer.AnalyzerUtils) ACCEPT(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.ACCEPT) ActionType(com.linkedin.kafka.cruisecontrol.analyzer.ActionType) Collectors(java.util.stream.Collectors) Broker(com.linkedin.kafka.cruisecontrol.model.Broker) Statistic(com.linkedin.kafka.cruisecontrol.common.Statistic) BalancingAction(com.linkedin.kafka.cruisecontrol.analyzer.BalancingAction) ProvisionRecommendation(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionRecommendation) ClusterModelStats(com.linkedin.kafka.cruisecontrol.model.ClusterModelStats) ReplicaSortFunctionFactory(com.linkedin.kafka.cruisecontrol.model.ReplicaSortFunctionFactory) ChangeType(com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaDistributionAbstractGoal.ChangeType) Comparator(java.util.Comparator) ProvisionStatus(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionStatus) Collections(java.util.Collections) ModelCompletenessRequirements(com.linkedin.kafka.cruisecontrol.monitor.ModelCompletenessRequirements) Broker(com.linkedin.kafka.cruisecontrol.model.Broker) TreeSet(java.util.TreeSet) Replica(com.linkedin.kafka.cruisecontrol.model.Replica) BalancingConstraint(com.linkedin.kafka.cruisecontrol.analyzer.BalancingConstraint)

Example 7 with OptimizationOptions

use of com.linkedin.kafka.cruisecontrol.analyzer.OptimizationOptions in project cruise-control by linkedin.

the class TopicReplicaDistributionGoal method rebalanceForBroker.

/**
 * Rebalance the given broker without violating the constraints of the current goal and optimized goals.
 *
 * @param broker         Broker to be balanced.
 * @param clusterModel   The state of the cluster.
 * @param optimizedGoals Optimized goals.
 * @param optimizationOptions Options to take into account during optimization.
 */
@Override
protected void rebalanceForBroker(Broker broker, ClusterModel clusterModel, Set<Goal> optimizedGoals, OptimizationOptions optimizationOptions) {
    LOG.debug("Rebalancing broker {} [limits] lower: {} upper: {}.", broker.id(), _balanceLowerLimitByTopic, _balanceUpperLimitByTopic);
    for (String topic : broker.topics()) {
        if (isTopicExcludedFromRebalance(topic)) {
            continue;
        }
        Collection<Replica> replicas = broker.replicasOfTopicInBroker(topic);
        int numTopicReplicas = replicas.size();
        int numOfflineTopicReplicas = GoalUtils.retainCurrentOfflineBrokerReplicas(broker, replicas).size();
        boolean isExcludedForReplicaMove = isExcludedForReplicaMove(broker);
        boolean requireLessReplicas = numOfflineTopicReplicas > 0 || numTopicReplicas > _balanceUpperLimitByTopic.get(topic) || isExcludedForReplicaMove;
        boolean requireMoreReplicas = !isExcludedForReplicaMove && broker.isAlive() && numTopicReplicas - numOfflineTopicReplicas < _balanceLowerLimitByTopic.get(topic);
        if (skipBrokerRebalance(broker, clusterModel, replicas, requireLessReplicas, requireMoreReplicas, numOfflineTopicReplicas > 0, optimizationOptions.onlyMoveImmigrantReplicas())) {
            continue;
        }
        // Update broker ids over the balance limit for logging purposes.
        if (requireLessReplicas && rebalanceByMovingReplicasOut(broker, topic, clusterModel, optimizedGoals, optimizationOptions)) {
            _brokerIdsAboveBalanceUpperLimitByTopic.computeIfAbsent(topic, t -> new HashSet<>()).add(broker.id());
            LOG.debug("Failed to sufficiently decrease replicas of topic {} in broker {} with replica movements. Replicas: {}.", topic, broker.id(), broker.numReplicasOfTopicInBroker(topic));
        }
        if (requireMoreReplicas && rebalanceByMovingReplicasIn(broker, topic, clusterModel, optimizedGoals, optimizationOptions)) {
            _brokerIdsUnderBalanceLowerLimitByTopic.computeIfAbsent(topic, t -> new HashSet<>()).add(broker.id());
            LOG.debug("Failed to sufficiently increase replicas of topic {} in broker {} with replica movements. Replicas: {}.", topic, broker.id(), broker.numReplicasOfTopicInBroker(topic));
        }
        if (!_brokerIdsAboveBalanceUpperLimitByTopic.getOrDefault(topic, Collections.emptySet()).contains(broker.id()) && !_brokerIdsUnderBalanceLowerLimitByTopic.getOrDefault(topic, Collections.emptySet()).contains(broker.id())) {
            LOG.debug("Successfully balanced replicas of topic {} in broker {} by moving replicas. Replicas: {}", topic, broker.id(), broker.numReplicasOfTopicInBroker(topic));
        }
    }
}
Also used : Replica(com.linkedin.kafka.cruisecontrol.model.Replica) SortedReplicasHelper(com.linkedin.kafka.cruisecontrol.model.SortedReplicasHelper) OptimizationOptions(com.linkedin.kafka.cruisecontrol.analyzer.OptimizationOptions) SortedSet(java.util.SortedSet) REPLICA_REJECT(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.REPLICA_REJECT) MIN_NUM_VALID_WINDOWS_FOR_SELF_HEALING(com.linkedin.kafka.cruisecontrol.analyzer.goals.GoalUtils.MIN_NUM_VALID_WINDOWS_FOR_SELF_HEALING) PriorityQueue(java.util.PriorityQueue) ClusterModel(com.linkedin.kafka.cruisecontrol.model.ClusterModel) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) OptimizationFailureException(com.linkedin.kafka.cruisecontrol.exception.OptimizationFailureException) Map(java.util.Map) GoalUtils.replicaSortName(com.linkedin.kafka.cruisecontrol.analyzer.goals.GoalUtils.replicaSortName) ActionAcceptance(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance) Logger(org.slf4j.Logger) EPSILON(com.linkedin.kafka.cruisecontrol.analyzer.AnalyzerUtils.EPSILON) BalancingConstraint(com.linkedin.kafka.cruisecontrol.analyzer.BalancingConstraint) Collection(java.util.Collection) Set(java.util.Set) AnalyzerUtils(com.linkedin.kafka.cruisecontrol.analyzer.AnalyzerUtils) ACCEPT(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.ACCEPT) ActionType(com.linkedin.kafka.cruisecontrol.analyzer.ActionType) Collectors(java.util.stream.Collectors) Broker(com.linkedin.kafka.cruisecontrol.model.Broker) Statistic(com.linkedin.kafka.cruisecontrol.common.Statistic) BalancingAction(com.linkedin.kafka.cruisecontrol.analyzer.BalancingAction) ProvisionRecommendation(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionRecommendation) ClusterModelStats(com.linkedin.kafka.cruisecontrol.model.ClusterModelStats) ReplicaSortFunctionFactory(com.linkedin.kafka.cruisecontrol.model.ReplicaSortFunctionFactory) ChangeType(com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaDistributionAbstractGoal.ChangeType) Comparator(java.util.Comparator) ProvisionStatus(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionStatus) Collections(java.util.Collections) ModelCompletenessRequirements(com.linkedin.kafka.cruisecontrol.monitor.ModelCompletenessRequirements) Replica(com.linkedin.kafka.cruisecontrol.model.Replica) BalancingConstraint(com.linkedin.kafka.cruisecontrol.analyzer.BalancingConstraint) HashSet(java.util.HashSet)

Example 8 with OptimizationOptions

use of com.linkedin.kafka.cruisecontrol.analyzer.OptimizationOptions in project cruise-control by linkedin.

the class ReplicaDistributionGoal method rebalanceByMovingReplicasOut.

private boolean rebalanceByMovingReplicasOut(Broker broker, ClusterModel clusterModel, Set<Goal> optimizedGoals, OptimizationOptions optimizationOptions) {
    long moveStartTimeMs = System.currentTimeMillis();
    // Get the eligible brokers.
    SortedSet<Broker> candidateBrokers = new TreeSet<>(Comparator.comparingInt((Broker b) -> b.replicas().size()).thenComparingInt(Broker::id));
    candidateBrokers.addAll(_fixOfflineReplicasOnly ? clusterModel.aliveBrokers() : clusterModel.aliveBrokers().stream().filter(b -> b.replicas().size() < _balanceUpperLimit).collect(Collectors.toSet()));
    // If the source broker is excluded for replica move, set its upper limit to 0.
    int balanceUpperLimitForSourceBroker = isExcludedForReplicaMove(broker) ? 0 : _balanceUpperLimit;
    // Now let's move things around.
    boolean wasUnableToMoveOfflineReplica = false;
    boolean fastMode = optimizationOptions.fastMode();
    for (Replica replica : broker.trackedSortedReplicas(replicaSortName(this, false, false)).sortedReplicas(true)) {
        if (!replica.isCurrentOffline()) {
            if (fastMode && remainingTimeMs(_balancingConstraint.fastModePerBrokerMoveTimeoutMs(), moveStartTimeMs) <= 0) {
                LOG.debug("Move replicas out timeout in fast mode for broker {}.", broker.id());
                break;
            }
            if (wasUnableToMoveOfflineReplica && broker.replicas().size() <= balanceUpperLimitForSourceBroker) {
                // Was unable to move offline replicas from the broker, and remaining replica count is under the balance limit.
                return false;
            }
        }
        Broker b = maybeApplyBalancingAction(clusterModel, replica, candidateBrokers, ActionType.INTER_BROKER_REPLICA_MOVEMENT, optimizedGoals, optimizationOptions);
        // Only check if we successfully moved something.
        if (b != null) {
            if (broker.replicas().size() <= (broker.currentOfflineReplicas().isEmpty() ? balanceUpperLimitForSourceBroker : 0)) {
                return false;
            }
            // Remove and reinsert the broker so the order is correct.
            candidateBrokers.remove(b);
            if (b.replicas().size() < _balanceUpperLimit || _fixOfflineReplicasOnly) {
                candidateBrokers.add(b);
            }
        } else if (replica.isCurrentOffline()) {
            wasUnableToMoveOfflineReplica = true;
        }
    }
    // All the replicas has been moved away from the broker.
    return !broker.replicas().isEmpty();
}
Also used : Replica(com.linkedin.kafka.cruisecontrol.model.Replica) SortedReplicasHelper(com.linkedin.kafka.cruisecontrol.model.SortedReplicasHelper) OptimizationOptions(com.linkedin.kafka.cruisecontrol.analyzer.OptimizationOptions) SortedSet(java.util.SortedSet) REPLICA_REJECT(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.REPLICA_REJECT) PriorityQueue(java.util.PriorityQueue) ClusterModel(com.linkedin.kafka.cruisecontrol.model.ClusterModel) LoggerFactory(org.slf4j.LoggerFactory) TreeSet(java.util.TreeSet) OptimizationFailureException(com.linkedin.kafka.cruisecontrol.exception.OptimizationFailureException) GoalUtils.replicaSortName(com.linkedin.kafka.cruisecontrol.analyzer.goals.GoalUtils.replicaSortName) ActionAcceptance(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance) GoalUtils.remainingTimeMs(com.linkedin.kafka.cruisecontrol.analyzer.goals.GoalUtils.remainingTimeMs) Logger(org.slf4j.Logger) ProvisionResponse(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionResponse) BalancingConstraint(com.linkedin.kafka.cruisecontrol.analyzer.BalancingConstraint) Set(java.util.Set) AnalyzerUtils(com.linkedin.kafka.cruisecontrol.analyzer.AnalyzerUtils) ACCEPT(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.ACCEPT) DISK(com.linkedin.kafka.cruisecontrol.common.Resource.DISK) ActionType(com.linkedin.kafka.cruisecontrol.analyzer.ActionType) Collectors(java.util.stream.Collectors) Broker(com.linkedin.kafka.cruisecontrol.model.Broker) List(java.util.List) Statistic(com.linkedin.kafka.cruisecontrol.common.Statistic) BalancingAction(com.linkedin.kafka.cruisecontrol.analyzer.BalancingAction) ProvisionRecommendation(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionRecommendation) ClusterModelStats(com.linkedin.kafka.cruisecontrol.model.ClusterModelStats) ReplicaSortFunctionFactory(com.linkedin.kafka.cruisecontrol.model.ReplicaSortFunctionFactory) ChangeType(com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaDistributionAbstractGoal.ChangeType) Comparator(java.util.Comparator) ProvisionStatus(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionStatus) Collections(java.util.Collections) Broker(com.linkedin.kafka.cruisecontrol.model.Broker) TreeSet(java.util.TreeSet) Replica(com.linkedin.kafka.cruisecontrol.model.Replica) BalancingConstraint(com.linkedin.kafka.cruisecontrol.analyzer.BalancingConstraint)

Example 9 with OptimizationOptions

use of com.linkedin.kafka.cruisecontrol.analyzer.OptimizationOptions in project cruise-control by linkedin.

the class MinTopicLeadersPerBrokerGoal method maybeMoveLeaderOfTopicToBroker.

private void maybeMoveLeaderOfTopicToBroker(String topicMustHaveLeaderPerBroker, Broker broker, ClusterModel clusterModel, Set<Goal> optimizedGoals, OptimizationOptions optimizationOptions) throws OptimizationFailureException {
    int topicLeaderCountOnReceiverBroker = broker.numLeadersFor(topicMustHaveLeaderPerBroker);
    if (topicLeaderCountOnReceiverBroker >= minTopicLeadersPerBroker(topicMustHaveLeaderPerBroker)) {
        // This broker has enough leader replica(s) for the given topic
        return;
    }
    // Try to elect follower replica(s) of the interested topic on this broker to be leader
    List<Replica> followerReplicas = broker.trackedSortedReplicas(_replicaSortName).sortedReplicas(false).stream().filter(replica -> !replica.isLeader() && replica.topicPartition().topic().equals(topicMustHaveLeaderPerBroker)).collect(Collectors.toList());
    for (Replica followerReplica : followerReplicas) {
        Replica leader = clusterModel.partition(followerReplica.topicPartition()).leader();
        if (leader.broker().numLeadersFor(topicMustHaveLeaderPerBroker) > minTopicLeadersPerBroker(topicMustHaveLeaderPerBroker)) {
            if (maybeApplyBalancingAction(clusterModel, leader, Collections.singleton(broker), LEADERSHIP_MOVEMENT, optimizedGoals, optimizationOptions) != null) {
                topicLeaderCountOnReceiverBroker++;
                if (topicLeaderCountOnReceiverBroker >= minTopicLeadersPerBroker(topicMustHaveLeaderPerBroker)) {
                    // This broker satisfies this goal for the given topic
                    return;
                }
            }
        }
    }
    // Try to move leader replica(s) of the interested topic from other brokers to this broker
    PriorityQueue<Broker> brokersWithExcessiveLeaderToMove = getBrokersWithExcessiveLeaderToMove(topicMustHaveLeaderPerBroker, clusterModel, broker);
    while (!brokersWithExcessiveLeaderToMove.isEmpty()) {
        Broker brokerWithExcessiveLeaderToMove = brokersWithExcessiveLeaderToMove.poll();
        List<Replica> leadersOfTopic = brokerWithExcessiveLeaderToMove.trackedSortedReplicas(_replicaSortName).sortedReplicas(false).stream().filter(replica -> replica.isLeader() && replica.topicPartition().topic().equals(topicMustHaveLeaderPerBroker)).collect(Collectors.toList());
        boolean leaderMoved = false;
        int topicLeaderCountOnGiverBroker = leadersOfTopic.size();
        for (Replica leaderOfTopic : leadersOfTopic) {
            Broker destinationBroker = maybeApplyBalancingAction(clusterModel, leaderOfTopic, Collections.singleton(broker), INTER_BROKER_REPLICA_MOVEMENT, optimizedGoals, optimizationOptions);
            if (destinationBroker != null) {
                leaderMoved = true;
                // Successfully move one leader replica
                break;
            }
        }
        if (leaderMoved) {
            topicLeaderCountOnReceiverBroker++;
            if (topicLeaderCountOnReceiverBroker >= minTopicLeadersPerBroker(topicMustHaveLeaderPerBroker)) {
                // This broker satisfies this goal for the given topic
                return;
            }
            topicLeaderCountOnGiverBroker--;
            if (topicLeaderCountOnGiverBroker > minTopicLeadersPerBroker(topicMustHaveLeaderPerBroker)) {
                // Still have excessive topic leader to give
                brokersWithExcessiveLeaderToMove.add(brokerWithExcessiveLeaderToMove);
            }
        }
    }
    throw new OptimizationFailureException(String.format("[%s] Cannot make broker %d have at least %d leaders from topic %s.", name(), broker.id(), minTopicLeadersPerBroker(topicMustHaveLeaderPerBroker), topicMustHaveLeaderPerBroker));
}
Also used : Replica(com.linkedin.kafka.cruisecontrol.model.Replica) SortedReplicasHelper(com.linkedin.kafka.cruisecontrol.model.SortedReplicasHelper) OptimizationOptions(com.linkedin.kafka.cruisecontrol.analyzer.OptimizationOptions) SortedSet(java.util.SortedSet) REPLICA_REJECT(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.REPLICA_REJECT) PriorityQueue(java.util.PriorityQueue) ClusterModel(com.linkedin.kafka.cruisecontrol.model.ClusterModel) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) LEADERSHIP_MOVEMENT(com.linkedin.kafka.cruisecontrol.analyzer.ActionType.LEADERSHIP_MOVEMENT) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) OptimizationFailureException(com.linkedin.kafka.cruisecontrol.exception.OptimizationFailureException) Map(java.util.Map) GoalUtils.replicaSortName(com.linkedin.kafka.cruisecontrol.analyzer.goals.GoalUtils.replicaSortName) ActionAcceptance(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance) Logger(org.slf4j.Logger) BalancingConstraint(com.linkedin.kafka.cruisecontrol.analyzer.BalancingConstraint) Set(java.util.Set) ACCEPT(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.ACCEPT) ActionType(com.linkedin.kafka.cruisecontrol.analyzer.ActionType) Collectors(java.util.stream.Collectors) Broker(com.linkedin.kafka.cruisecontrol.model.Broker) Objects(java.util.Objects) List(java.util.List) BalancingAction(com.linkedin.kafka.cruisecontrol.analyzer.BalancingAction) ProvisionRecommendation(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionRecommendation) INTER_BROKER_REPLICA_MOVEMENT(com.linkedin.kafka.cruisecontrol.analyzer.ActionType.INTER_BROKER_REPLICA_MOVEMENT) AnalyzerConfig(com.linkedin.kafka.cruisecontrol.config.constants.AnalyzerConfig) ReplicaSortFunctionFactory(com.linkedin.kafka.cruisecontrol.model.ReplicaSortFunctionFactory) Pattern(java.util.regex.Pattern) Comparator(java.util.Comparator) ProvisionStatus(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionStatus) Utils(com.linkedin.kafka.cruisecontrol.common.Utils) Collections(java.util.Collections) ModelCompletenessRequirements(com.linkedin.kafka.cruisecontrol.monitor.ModelCompletenessRequirements) Broker(com.linkedin.kafka.cruisecontrol.model.Broker) OptimizationFailureException(com.linkedin.kafka.cruisecontrol.exception.OptimizationFailureException) Replica(com.linkedin.kafka.cruisecontrol.model.Replica) BalancingConstraint(com.linkedin.kafka.cruisecontrol.analyzer.BalancingConstraint)

Example 10 with OptimizationOptions

use of com.linkedin.kafka.cruisecontrol.analyzer.OptimizationOptions in project cruise-control by linkedin.

the class AbstractRackAwareGoal method rebalanceForBroker.

/**
 * Rebalance the given broker without violating the constraints of this custom rack aware goal and optimized goals.
 *
 * @param broker Broker to be balanced.
 * @param clusterModel The state of the cluster.
 * @param optimizedGoals Optimized goals.
 * @param optimizationOptions Options to take into account during optimization.
 * @param throwExceptionIfCannotMove {@code true} to throw an {@link OptimizationFailureException} in case a required
 * balancing action for a replica fails for all rack-aware eligible brokers, {@code false} to just log the failure and return.
 * This parameter enables selected goals fail early in case the unsatisfiability of a goal can be determined early.
 */
protected void rebalanceForBroker(Broker broker, ClusterModel clusterModel, Set<Goal> optimizedGoals, OptimizationOptions optimizationOptions, boolean throwExceptionIfCannotMove) throws OptimizationFailureException {
    for (Replica replica : broker.trackedSortedReplicas(replicaSortName(this, false, false)).sortedReplicas(true)) {
        if (broker.isAlive() && !broker.currentOfflineReplicas().contains(replica) && shouldKeepInTheCurrentBroker(replica, clusterModel)) {
            continue;
        }
        // The relevant rack awareness condition is violated. Move replica to an eligible broker
        SortedSet<Broker> eligibleBrokers = rackAwareEligibleBrokers(replica, clusterModel);
        if (maybeApplyBalancingAction(clusterModel, replica, eligibleBrokers, ActionType.INTER_BROKER_REPLICA_MOVEMENT, optimizedGoals, optimizationOptions) == null) {
            if (throwExceptionIfCannotMove) {
                Set<String> partitionRackIds = clusterModel.partition(replica.topicPartition()).partitionBrokers().stream().map(partitionBroker -> partitionBroker.rack().id()).collect(Collectors.toSet());
                ProvisionRecommendation recommendation = new ProvisionRecommendation.Builder(ProvisionStatus.UNDER_PROVISIONED).numBrokers(1).excludedRackIds(partitionRackIds).build();
                throw new OptimizationFailureException(String.format("[%s] Cannot move %s to %s.", name(), replica, eligibleBrokers), recommendation);
            }
            LOG.debug("Cannot move replica {} to any broker in {}", replica, eligibleBrokers);
        }
    }
}
Also used : Replica(com.linkedin.kafka.cruisecontrol.model.Replica) BROKER_REJECT(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.BROKER_REJECT) Logger(org.slf4j.Logger) OptimizationOptions(com.linkedin.kafka.cruisecontrol.analyzer.OptimizationOptions) SortedSet(java.util.SortedSet) REPLICA_REJECT(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.REPLICA_REJECT) MIN_NUM_VALID_WINDOWS_FOR_SELF_HEALING(com.linkedin.kafka.cruisecontrol.analyzer.goals.GoalUtils.MIN_NUM_VALID_WINDOWS_FOR_SELF_HEALING) ClusterModel(com.linkedin.kafka.cruisecontrol.model.ClusterModel) LoggerFactory(org.slf4j.LoggerFactory) Set(java.util.Set) ACCEPT(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.ACCEPT) ActionType(com.linkedin.kafka.cruisecontrol.analyzer.ActionType) Collectors(java.util.stream.Collectors) Broker(com.linkedin.kafka.cruisecontrol.model.Broker) BalancingAction(com.linkedin.kafka.cruisecontrol.analyzer.BalancingAction) ProvisionRecommendation(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionRecommendation) OptimizationFailureException(com.linkedin.kafka.cruisecontrol.exception.OptimizationFailureException) GoalUtils.replicaSortName(com.linkedin.kafka.cruisecontrol.analyzer.goals.GoalUtils.replicaSortName) ProvisionStatus(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionStatus) ActionAcceptance(com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance) ModelCompletenessRequirements(com.linkedin.kafka.cruisecontrol.monitor.ModelCompletenessRequirements) ProvisionRecommendation(com.linkedin.kafka.cruisecontrol.analyzer.ProvisionRecommendation) Broker(com.linkedin.kafka.cruisecontrol.model.Broker) OptimizationFailureException(com.linkedin.kafka.cruisecontrol.exception.OptimizationFailureException) Replica(com.linkedin.kafka.cruisecontrol.model.Replica)

Aggregations

OptimizationOptions (com.linkedin.kafka.cruisecontrol.analyzer.OptimizationOptions)16 ClusterModel (com.linkedin.kafka.cruisecontrol.model.ClusterModel)15 ActionAcceptance (com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance)9 ACCEPT (com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.ACCEPT)9 REPLICA_REJECT (com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.REPLICA_REJECT)9 ActionType (com.linkedin.kafka.cruisecontrol.analyzer.ActionType)9 BalancingAction (com.linkedin.kafka.cruisecontrol.analyzer.BalancingAction)9 GoalUtils.replicaSortName (com.linkedin.kafka.cruisecontrol.analyzer.goals.GoalUtils.replicaSortName)9 OptimizationFailureException (com.linkedin.kafka.cruisecontrol.exception.OptimizationFailureException)9 Broker (com.linkedin.kafka.cruisecontrol.model.Broker)9 Replica (com.linkedin.kafka.cruisecontrol.model.Replica)9 Set (java.util.Set)9 SortedSet (java.util.SortedSet)9 Collectors (java.util.stream.Collectors)9 Logger (org.slf4j.Logger)9 LoggerFactory (org.slf4j.LoggerFactory)9 BalancingConstraint (com.linkedin.kafka.cruisecontrol.analyzer.BalancingConstraint)8 ProvisionRecommendation (com.linkedin.kafka.cruisecontrol.analyzer.ProvisionRecommendation)8 ProvisionStatus (com.linkedin.kafka.cruisecontrol.analyzer.ProvisionStatus)8 ReplicaSortFunctionFactory (com.linkedin.kafka.cruisecontrol.model.ReplicaSortFunctionFactory)8