Search in sources :

Example 31 with Broker

use of com.linkedin.kafka.cruisecontrol.model.Broker in project cruise-control by linkedin.

the class ReplicaDistributionGoal method actionAcceptance.

/**
 * Check whether the given action is acceptable by this goal. An action is acceptable if the number of replicas at
 * (1) the source broker does not go under the allowed limit.
 * (2) the destination broker does not go over the allowed limit.
 *
 * @param action Action to be checked for acceptance.
 * @param clusterModel The state of the cluster.
 * @return {@link ActionAcceptance#ACCEPT} if the action is acceptable by this goal,
 * {@link ActionAcceptance#REPLICA_REJECT} otherwise.
 */
@Override
public ActionAcceptance actionAcceptance(BalancingAction action, ClusterModel clusterModel) {
    switch(action.balancingAction()) {
        case REPLICA_SWAP:
        case LEADERSHIP_MOVEMENT:
            return ACCEPT;
        case REPLICA_MOVEMENT:
            Broker sourceBroker = clusterModel.broker(action.sourceBrokerId());
            Broker destinationBroker = clusterModel.broker(action.destinationBrokerId());
            // Check that destination and source would not become unbalanced.
            return (isReplicaCountUnderBalanceUpperLimitAfterChange(destinationBroker, ADD) && isReplicaCountAboveBalanceLowerLimitAfterChange(sourceBroker, REMOVE)) ? ACCEPT : REPLICA_REJECT;
        default:
            throw new IllegalArgumentException("Unsupported balancing action " + action.balancingAction() + " is provided.");
    }
}
Also used : Broker(com.linkedin.kafka.cruisecontrol.model.Broker)

Example 32 with Broker

use of com.linkedin.kafka.cruisecontrol.model.Broker in project cruise-control by linkedin.

the class ReplicaDistributionGoal method selfSatisfied.

/**
 * Check if requirements of this goal are not violated if this proposal is applied to the given cluster state,
 * false otherwise.
 *
 * @param clusterModel The state of the cluster.
 * @param action     Proposal containing information about
 * @return True if requirements of this goal are not violated if this proposal is applied to the given cluster state,
 * false otherwise.
 */
@Override
protected boolean selfSatisfied(ClusterModel clusterModel, BalancingAction action) {
    Broker destinationBroker = clusterModel.broker(action.destinationBrokerId());
    Broker sourceBroker = clusterModel.broker(action.sourceBrokerId());
    // If the source broker is dead and currently self healing dead brokers only, then the proposal must be executed.
    if (!sourceBroker.isAlive() && _selfHealingDeadBrokersOnly) {
        return true;
    }
    // Check that destination and source would not become unbalanced.
    return isReplicaCountUnderBalanceUpperLimitAfterChange(destinationBroker, ADD) && isReplicaCountAboveBalanceLowerLimitAfterChange(sourceBroker, REMOVE);
}
Also used : Broker(com.linkedin.kafka.cruisecontrol.model.Broker)

Example 33 with Broker

use of com.linkedin.kafka.cruisecontrol.model.Broker in project cruise-control by linkedin.

the class ReplicaDistributionTarget method isEligibleForReplica.

private boolean isEligibleForReplica(ClusterModel clusterModel, Replica replica, int candidateBrokerId) {
    Set<Broker> newBrokers = clusterModel.newBrokers();
    Broker candidateBroker = clusterModel.broker(candidateBrokerId);
    return newBrokers.isEmpty() || candidateBroker.isNew() || replica.originalBroker() == candidateBroker;
}
Also used : Broker(com.linkedin.kafka.cruisecontrol.model.Broker)

Example 34 with Broker

use of com.linkedin.kafka.cruisecontrol.model.Broker in project cruise-control by linkedin.

the class ResourceDistributionGoal method selfSatisfied.

/**
 * Check if requirements of this goal are not violated if this action is applied to the given cluster state,
 * false otherwise. An action is acceptable if: (1) destination broker utilization for the given resource is less
 * than the source broker utilization. (2) movement is acceptable (i.e. under the broker balance limit for balanced
 * resources) for already balanced resources. Already balanced resources are the ones that have gone through the
 * "resource distribution" process specified in this goal.
 *
 * @param clusterModel The state of the cluster.
 * @param action Action containing information about potential modification to the given cluster model.
 * @return True if requirements of this goal are not violated if this action is applied to the given cluster state,
 * false otherwise.
 */
@Override
protected boolean selfSatisfied(ClusterModel clusterModel, BalancingAction action) {
    Broker destinationBroker = clusterModel.broker(action.destinationBrokerId());
    Replica sourceReplica = clusterModel.broker(action.sourceBrokerId()).replica(action.topicPartition());
    // must be executed.
    if (!sourceReplica.broker().isAlive() && _selfHealingDeadBrokersOnly) {
        return action.balancingAction() != REPLICA_SWAP;
    }
    switch(action.balancingAction()) {
        case REPLICA_SWAP:
            Replica destinationReplica = destinationBroker.replica(action.destinationTopicPartition());
            double sourceUtilizationDelta = destinationReplica.load().expectedUtilizationFor(resource()) - sourceReplica.load().expectedUtilizationFor(resource());
            return sourceUtilizationDelta != 0 && !isSwapViolatingLimit(sourceReplica, destinationReplica);
        case REPLICA_MOVEMENT:
        case LEADERSHIP_MOVEMENT:
            // Check that current destination would not become more unbalanced.
            return isLoadUnderBalanceUpperLimitAfterChange(sourceReplica.load(), destinationBroker, ADD) && isLoadAboveBalanceLowerLimitAfterChange(sourceReplica.load(), sourceReplica.broker(), REMOVE);
        default:
            throw new IllegalArgumentException("Unsupported balancing action " + action.balancingAction() + " is provided.");
    }
}
Also used : Broker(com.linkedin.kafka.cruisecontrol.model.Broker) Replica(com.linkedin.kafka.cruisecontrol.model.Replica)

Example 35 with Broker

use of com.linkedin.kafka.cruisecontrol.model.Broker in project cruise-control by linkedin.

the class ResourceDistributionGoal method rebalanceByMovingLoadOut.

private boolean rebalanceByMovingLoadOut(Broker broker, ClusterModel clusterModel, Set<Goal> optimizedGoals, ActionType actionType, Set<String> excludedTopics) {
    // Get the eligible brokers.
    SortedSet<Broker> candidateBrokers = new TreeSet<>(Comparator.comparingDouble(this::utilizationPercentage).thenComparingInt(Broker::id));
    if (_selfHealingDeadBrokersOnly) {
        candidateBrokers.addAll(clusterModel.healthyBrokers());
    } else {
        candidateBrokers.addAll(clusterModel.healthyBrokersUnderThreshold(resource(), _balanceUpperThreshold));
    }
    // Get the replicas to rebalance.
    List<Replica> replicasToMove;
    if (actionType == LEADERSHIP_MOVEMENT) {
        // Only take leader replicas to move leaders.
        replicasToMove = new ArrayList<>(broker.leaderReplicas());
        replicasToMove.sort((r1, r2) -> Double.compare(r2.load().expectedUtilizationFor(resource()), r1.load().expectedUtilizationFor(resource())));
    } else {
        // Take all replicas for replica movements.
        replicasToMove = broker.sortedReplicas(resource());
    }
    // Now let's move things around.
    for (Replica replica : replicasToMove) {
        if (shouldExclude(replica, excludedTopics)) {
            continue;
        }
        // It does not make sense to move a replica without utilization from a live broker.
        if (replica.load().expectedUtilizationFor(resource()) == 0.0 && broker.isAlive()) {
            break;
        }
        // An optimization for leader movements.
        SortedSet<Broker> eligibleBrokers;
        if (actionType == LEADERSHIP_MOVEMENT) {
            eligibleBrokers = new TreeSet<>(Comparator.comparingDouble(this::utilizationPercentage).thenComparingInt(Broker::id));
            clusterModel.partition(replica.topicPartition()).followerBrokers().forEach(b -> {
                if (candidateBrokers.contains(b)) {
                    eligibleBrokers.add(b);
                }
            });
        } else {
            eligibleBrokers = candidateBrokers;
        }
        Broker b = maybeApplyBalancingAction(clusterModel, replica, eligibleBrokers, actionType, optimizedGoals);
        // Only check if we successfully moved something.
        if (b != null) {
            if (isLoadUnderBalanceUpperLimit(broker)) {
                return false;
            }
            // Remove and reinsert the broker so the order is correct.
            candidateBrokers.remove(b);
            if (utilizationPercentage(b) < _balanceUpperThreshold) {
                candidateBrokers.add(b);
            }
        }
    }
    // we consider it as not over limit.
    return !broker.replicas().isEmpty();
}
Also used : Broker(com.linkedin.kafka.cruisecontrol.model.Broker) TreeSet(java.util.TreeSet) Replica(com.linkedin.kafka.cruisecontrol.model.Replica)

Aggregations

Broker (com.linkedin.kafka.cruisecontrol.model.Broker)50 Replica (com.linkedin.kafka.cruisecontrol.model.Replica)27 BalancingConstraint (com.linkedin.kafka.cruisecontrol.analyzer.BalancingConstraint)15 OptimizationFailureException (com.linkedin.kafka.cruisecontrol.exception.OptimizationFailureException)12 HashSet (java.util.HashSet)12 ArrayList (java.util.ArrayList)10 TreeSet (java.util.TreeSet)10 BalancingAction (com.linkedin.kafka.cruisecontrol.analyzer.BalancingAction)9 Resource (com.linkedin.kafka.cruisecontrol.common.Resource)9 ClusterModel (com.linkedin.kafka.cruisecontrol.model.ClusterModel)9 List (java.util.List)9 ActionAcceptance (com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance)8 ClusterModelStats (com.linkedin.kafka.cruisecontrol.model.ClusterModelStats)7 ActionType (com.linkedin.kafka.cruisecontrol.analyzer.ActionType)6 ModelCompletenessRequirements (com.linkedin.kafka.cruisecontrol.monitor.ModelCompletenessRequirements)6 Set (java.util.Set)6 Logger (org.slf4j.Logger)6 LoggerFactory (org.slf4j.LoggerFactory)6 ACCEPT (com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.ACCEPT)5 REPLICA_REJECT (com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance.REPLICA_REJECT)5