use of com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance in project cruise-control by linkedin.
the class AbstractGoal method maybeApplySwapAction.
/**
* Attempt to swap the given source replica with a replica from the candidate replicas to swap with. The function
* returns the swapped in replica if succeeded, null otherwise.
* All the replicas in the given candidateReplicasToSwapWith must be from the same broker.
*
* @param clusterModel The state of the cluster.
* @param sourceReplica Replica to be swapped with.
* @param candidateReplicasToSwapWith Candidate replicas from the same destination broker to swap in the order of
* attempts to swap.
* @param optimizedGoals Optimized goals.
* @return True the swapped in replica if succeeded, null otherwise.
*/
Replica maybeApplySwapAction(ClusterModel clusterModel, Replica sourceReplica, SortedSet<Replica> candidateReplicasToSwapWith, Set<Goal> optimizedGoals) {
SortedSet<Replica> eligibleReplicas = getEligibleReplicasForSwap(clusterModel, sourceReplica, candidateReplicasToSwapWith);
if (eligibleReplicas.isEmpty()) {
return null;
}
Broker destinationBroker = eligibleReplicas.first().broker();
for (Replica destinationReplica : eligibleReplicas) {
BalancingAction swapProposal = new BalancingAction(sourceReplica.topicPartition(), sourceReplica.broker().id(), destinationBroker.id(), ActionType.REPLICA_SWAP, destinationReplica.topicPartition());
// 3. The movement is acceptable by the previously optimized goals.
if (!legitMove(sourceReplica, destinationBroker, ActionType.REPLICA_MOVEMENT)) {
LOG.trace("Swap from source to destination is not legit for {}.", swapProposal);
return null;
}
if (!legitMove(destinationReplica, sourceReplica.broker(), ActionType.REPLICA_MOVEMENT)) {
LOG.trace("Swap from destination to source is not legit for {}.", swapProposal);
continue;
}
// The current goal is expected to know whether a swap is doable between given brokers.
if (!selfSatisfied(clusterModel, swapProposal)) {
// Unable to satisfy proposal for this eligible replica and the remaining eligible replicas in the list.
LOG.trace("Unable to self-satisfy swap proposal {}.", swapProposal);
return null;
}
ActionAcceptance acceptance = AnalyzerUtils.isProposalAcceptableForOptimizedGoals(optimizedGoals, swapProposal, clusterModel);
LOG.trace("Trying to apply legit and self-satisfied swap {}, actionAcceptance = {}.", swapProposal, acceptance);
if (acceptance == ACCEPT) {
Broker sourceBroker = sourceReplica.broker();
clusterModel.relocateReplica(sourceReplica.topicPartition(), sourceBroker.id(), destinationBroker.id());
clusterModel.relocateReplica(destinationReplica.topicPartition(), destinationBroker.id(), sourceBroker.id());
return destinationReplica;
} else if (acceptance == BROKER_REJECT) {
// Unable to swap the given source replica with any replicas in the destination broker.
return null;
}
}
return null;
}
use of com.linkedin.kafka.cruisecontrol.analyzer.ActionAcceptance in project cruise-control by linkedin.
the class AbstractGoal method maybeApplyBalancingAction.
/**
* Attempt to apply the given balancing action to the given replica in the given cluster. The application
* considers the candidate brokers as the potential destination brokers for replica movement or the location of
* followers for leadership transfer. If the movement attempt succeeds, the function returns the broker id of the
* destination, otherwise the function returns null.
*
* @param clusterModel The state of the cluster.
* @param replica Replica to be applied the given balancing action.
* @param candidateBrokers Candidate brokers as the potential destination brokers for replica movement or the location
* of followers for leadership transfer.
* @param action Balancing action.
* @param optimizedGoals Optimized goals.
* @return Broker id of the destination if the movement attempt succeeds, null otherwise.
*/
protected Broker maybeApplyBalancingAction(ClusterModel clusterModel, Replica replica, Collection<Broker> candidateBrokers, ActionType action, Set<Goal> optimizedGoals) {
// In self healing mode, allow a move only from dead to alive brokers.
if (!clusterModel.deadBrokers().isEmpty() && replica.originalBroker().isAlive()) {
// return null;
LOG.trace("Applying {} to a replica in a healthy broker in self-healing mode.", action);
}
Collection<Broker> eligibleBrokers = getEligibleBrokers(clusterModel, replica, candidateBrokers);
for (Broker broker : eligibleBrokers) {
BalancingAction proposal = new BalancingAction(replica.topicPartition(), replica.broker().id(), broker.id(), action);
if (!legitMove(replica, broker, action)) {
LOG.trace("Replica move is not legit for {}.", proposal);
continue;
}
if (!selfSatisfied(clusterModel, proposal)) {
LOG.trace("Unable to self-satisfy proposal {}.", proposal);
continue;
}
ActionAcceptance acceptance = AnalyzerUtils.isProposalAcceptableForOptimizedGoals(optimizedGoals, proposal, clusterModel);
LOG.trace("Trying to apply legit and self-satisfied action {}, actionAcceptance = {}", proposal, acceptance);
if (acceptance == ACCEPT) {
if (action == ActionType.LEADERSHIP_MOVEMENT) {
clusterModel.relocateLeadership(replica.topicPartition(), replica.broker().id(), broker.id());
} else if (action == ActionType.REPLICA_MOVEMENT) {
clusterModel.relocateReplica(replica.topicPartition(), replica.broker().id(), broker.id());
}
return broker;
}
}
return null;
}
Aggregations