-
Notifications
You must be signed in to change notification settings - Fork 0
Port TopicLeaderDistributionGoal and ExecutionTaskPlanner changes #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 3.0.4-liftoff
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,7 @@ | |
| import java.util.SortedMap; | ||
| import java.util.TreeMap; | ||
| import java.util.function.Function; | ||
| import java.util.stream.Collectors; | ||
| import org.apache.kafka.common.TopicPartition; | ||
|
|
||
| import static com.linkedin.cruisecontrol.common.utils.Utils.validateNotNull; | ||
|
|
@@ -203,6 +204,15 @@ public int numLeadersFor(String topicName) { | |
| return (int) replicasOfTopicInBroker(topicName).stream().filter(Replica::isLeader).count(); | ||
| } | ||
|
|
||
| /** | ||
| * Get leader replicas for topic. | ||
| * @param topic Topic of the requested replicas. | ||
| * @return Leader replicas in this broker sharing the given topic. | ||
| */ | ||
| public Collection<Replica> leadersFor(String topic) { | ||
| return replicasOfTopicInBroker(topic).stream().filter(Replica::isLeader).collect(Collectors.toList()); | ||
| } | ||
|
|
||
|
Comment on lines
+207
to
+215
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I replaced |
||
| /** | ||
| * @return {@code true} if the broker is not dead, {@code false} otherwise. | ||
| */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -671,6 +671,19 @@ public int numTopicReplicas(String topic) { | |
| return _numReplicasByTopic.getOrDefault(topic, 0); | ||
| } | ||
|
|
||
| /** | ||
| * Get the number of leader replicas with the given topic name in cluster. | ||
| * @param topic Name of the topic for which the number of leader replicas in cluster will be counted. | ||
| * @return Number of leader replicas with the given topic name in cluster. | ||
| */ | ||
| public int numTopicLeaders(String topic) { | ||
| int numTopicLeaders = 0; | ||
| for (Broker broker : brokers()) { | ||
| numTopicLeaders += broker.numLeadersFor(topic); | ||
| } | ||
| return numTopicLeaders; | ||
| } | ||
|
Comment on lines
+679
to
+685
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| /** | ||
| * Get the number of leader replicas in cluster. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,7 @@ public class ClusterModelStats { | |
| private final Map<Statistic, Number> _replicaStats; | ||
| private final Map<Statistic, Number> _leaderReplicaStats; | ||
| private final Map<Statistic, Number> _topicReplicaStats; | ||
| private final Map<Statistic, Number> _topicLeaderStats; | ||
| private int _numBrokers; | ||
| private int _numReplicasInCluster; | ||
| private int _numPartitionsWithOfflineReplicas; | ||
|
|
@@ -62,6 +63,7 @@ public class ClusterModelStats { | |
| _replicaStats = new HashMap<>(); | ||
| _leaderReplicaStats = new HashMap<>(); | ||
| _topicReplicaStats = new HashMap<>(); | ||
| _topicLeaderStats = new HashMap<>(); | ||
| _numBrokers = 0; | ||
| _numReplicasInCluster = 0; | ||
| _numPartitionsWithOfflineReplicas = 0; | ||
|
|
@@ -94,6 +96,7 @@ ClusterModelStats populate(ClusterModel clusterModel, BalancingConstraint balanc | |
| numForReplicas(clusterModel, brokers, aliveBrokers); | ||
| numForLeaderReplicas(brokers, aliveBrokers); | ||
| numForAvgTopicReplicas(clusterModel, brokers, topics); | ||
| numForAvgTopicLeaders(clusterModel, brokers, topics, aliveBrokers); | ||
| _utilizationMatrix = clusterModel.utilizationMatrix(); | ||
| _numSnapshotWindows = clusterModel.load().numWindows(); | ||
| _monitoredPartitionsRatio = clusterModel.monitoredPartitionsRatio(); | ||
|
|
@@ -136,6 +139,13 @@ public Map<Statistic, Number> topicReplicaStats() { | |
| return Collections.unmodifiableMap(_topicReplicaStats); | ||
| } | ||
|
|
||
| /** | ||
| * @return Topic leader stats for the cluster instance that the object was populated with. | ||
| */ | ||
| public Map<Statistic, Number> topicLeaderStats() { | ||
| return Collections.unmodifiableMap(_topicLeaderStats); | ||
| } | ||
|
|
||
| /** | ||
| * @return The number of brokers for the cluster instance that the object was populated with. | ||
| */ | ||
|
|
@@ -475,6 +485,49 @@ private void numForAvgTopicReplicas(ClusterModel clusterModel, SortedSet<Broker> | |
| _topicReplicaStats.put(Statistic.ST_DEV, _topicReplicaStats.get(Statistic.ST_DEV).doubleValue() / _numTopics); | ||
| } | ||
|
|
||
| /** | ||
| * Generate statistics for leader replicas of each topic in the given cluster. | ||
| * Average and standard deviation calculations are based on alive brokers. | ||
| * @param clusterModel The state of the cluster. | ||
| * @param brokers Brokers in the cluster. | ||
| * @param topics Topics in the cluster. | ||
| * @param aliveBrokers Alive brokers in the cluster. | ||
| */ | ||
| private void numForAvgTopicLeaders(ClusterModel clusterModel, | ||
| SortedSet<Broker> brokers, | ||
| Set<String> topics, | ||
| Set<Broker> aliveBrokers) { | ||
|
Comment on lines
+496
to
+499
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated
|
||
| _topicLeaderStats.put(Statistic.AVG, 0.0); | ||
| _topicLeaderStats.put(Statistic.MAX, 0); | ||
| _topicLeaderStats.put(Statistic.MIN, Integer.MAX_VALUE); | ||
| _topicLeaderStats.put(Statistic.ST_DEV, 0.0); | ||
| int numAliveBrokers = aliveBrokers.size(); | ||
| for (String topic : topics) { | ||
| int maxTopicLeadersInBroker = 0; | ||
| int minTopicLeadersInBroker = Integer.MAX_VALUE; | ||
| double avgTopicLeaders = ((double) clusterModel.numTopicLeaders(topic)) / numAliveBrokers; | ||
| double variance = 0.0; | ||
| for (Broker broker : brokers) { | ||
| int numTopicLeadersInBroker = broker.numLeadersFor(topic); | ||
| maxTopicLeadersInBroker = Math.max(maxTopicLeadersInBroker, numTopicLeadersInBroker); | ||
| minTopicLeadersInBroker = Math.min(minTopicLeadersInBroker, numTopicLeadersInBroker); | ||
| if (broker.isAlive()) { | ||
| // Standard deviation of leader replicas in alive brokers. | ||
| variance += (Math.pow(numTopicLeadersInBroker - avgTopicLeaders, 2) / numAliveBrokers); | ||
| } | ||
| } | ||
| _topicLeaderStats.put(Statistic.AVG, _topicLeaderStats.get(Statistic.AVG).doubleValue() + avgTopicLeaders); | ||
| _topicLeaderStats.put(Statistic.MAX, | ||
| Math.max(_topicLeaderStats.get(Statistic.MAX).intValue(), maxTopicLeadersInBroker)); | ||
| _topicLeaderStats.put(Statistic.MIN, | ||
| Math.min(_topicLeaderStats.get(Statistic.MIN).intValue(), minTopicLeadersInBroker)); | ||
| _topicLeaderStats.put(Statistic.ST_DEV, (Double) _topicLeaderStats.get(Statistic.ST_DEV) + Math.sqrt(variance)); | ||
| } | ||
|
|
||
| _topicLeaderStats.put(Statistic.AVG, _topicLeaderStats.get(Statistic.AVG).doubleValue() / _numTopics); | ||
| _topicLeaderStats.put(Statistic.ST_DEV, _topicLeaderStats.get(Statistic.ST_DEV).doubleValue() / _numTopics); | ||
| } | ||
|
|
||
| /** | ||
| * Generate statistics for disks in the given cluster. | ||
| * For each alive disk on disk broker in the cluster, check whether its utilization percentage is within the range centered | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -288,8 +288,8 @@ public void testGetInterBrokerPartitionMovementTasks() { | |
| partitionMovementTasks = prioritizeSmallMovementPlanner.getInterBrokerReplicaMovementTasks(readyBrokers, Collections.emptySet(), | ||
| _defaultPartitionsMaxCap); | ||
| assertEquals("First task", _partitionMovement0, partitionMovementTasks.get(0).proposal()); | ||
| assertEquals("Second task", _partitionMovement2, partitionMovementTasks.get(1).proposal()); | ||
| assertEquals("Third task", _partitionMovement3, partitionMovementTasks.get(2).proposal()); | ||
| assertEquals("Second task", _partitionMovement3, partitionMovementTasks.get(1).proposal()); | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added these test changes to |
||
| assertEquals("Third task", _partitionMovement2, partitionMovementTasks.get(2).proposal()); | ||
| assertEquals("Fourth task", _partitionMovement1, partitionMovementTasks.get(3).proposal()); | ||
|
|
||
| smallUrpMovementPlanner.addExecutionProposals(proposals, strategyOptions, null); | ||
|
|
@@ -356,8 +356,8 @@ public void testGetInterBrokerPartitionMovementWithMinIsrTasks() { | |
| List<ExecutionTask> partitionMovementTasks | ||
| = prioritizeOneAboveMinIsrMovementPlanner.getInterBrokerReplicaMovementTasks(readyBrokers, Collections.emptySet(), _defaultPartitionsMaxCap); | ||
| assertEquals("First task", _rf4PartitionMovement2, partitionMovementTasks.get(0).proposal()); | ||
| assertEquals("Second task", _rf4PartitionMovement3, partitionMovementTasks.get(1).proposal()); | ||
| assertEquals("Third task", _rf4PartitionMovement1, partitionMovementTasks.get(2).proposal()); | ||
| assertEquals("Second task", _rf4PartitionMovement1, partitionMovementTasks.get(1).proposal()); | ||
| assertEquals("Third task", _rf4PartitionMovement3, partitionMovementTasks.get(2).proposal()); | ||
| assertEquals("Fourth task", _rf4PartitionMovement0, partitionMovementTasks.get(3).proposal()); | ||
| } | ||
|
|
||
|
|
@@ -407,8 +407,8 @@ public void testDynamicConfigReplicaMovementStrategy() { | |
| planner.addExecutionProposals(proposals, strategyOptions, new PrioritizeSmallReplicaMovementStrategy()); | ||
| partitionMovementTasks = planner.getInterBrokerReplicaMovementTasks(readyBrokers, Collections.emptySet(), _defaultPartitionsMaxCap); | ||
| assertEquals("First task", _partitionMovement0, partitionMovementTasks.get(0).proposal()); | ||
| assertEquals("Second task", _partitionMovement2, partitionMovementTasks.get(1).proposal()); | ||
| assertEquals("Third task", _partitionMovement3, partitionMovementTasks.get(2).proposal()); | ||
| assertEquals("Second task", _partitionMovement3, partitionMovementTasks.get(1).proposal()); | ||
| assertEquals("Third task", _partitionMovement2, partitionMovementTasks.get(2).proposal()); | ||
| assertEquals("Fourth task", _partitionMovement1, partitionMovementTasks.get(3).proposal()); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uses the
doubleprimitive instead ofDoubleforBalancingConstraint.topicLeaderBalancePercentage, matching the refactor in the other methods of the class.