Search in sources :

Example 1 with BrokerCapacityInfo

use of com.linkedin.kafka.cruisecontrol.config.BrokerCapacityInfo in project cruise-control by linkedin.

the class LoadMonitor method populateClusterCapacity.

private void populateClusterCapacity(boolean populateReplicaPlacementInfo, boolean allowCapacityEstimation, ClusterModel clusterModel, Cluster cluster) throws TimeoutException, BrokerCapacityResolutionException {
    // Create the racks and brokers.
    // If broker capacity is allowed to estimate broker capacity, shuffle nodes before getting their capacity from the
    // capacity resolver. This is good for the capacity resolver to estimate the capacity of the nodes, for which the
    // capacity retrieval has failed.
    // The use case for this estimation is that if the capacity of one of the nodes is not available (e.g. due to some
    // 3rd party service issue), the capacity resolver may want to use the capacity of a peer node as the capacity for
    // that node.
    // To this end, Cruise Control handles the case that the first node is problematic so the capacity resolver does
    // not have the chance to get the capacity for the other nodes.
    // Shuffling the node order helps, as the problematic node is unlikely to always be the first node in the list.
    List<Node> shuffledNodes = allowCapacityEstimation ? new ArrayList<>(cluster.nodes()) : cluster.nodes();
    if (allowCapacityEstimation) {
        Collections.shuffle(shuffledNodes);
    }
    for (Node node : shuffledNodes) {
        // If the rack is not specified, we use the host info as rack info.
        String rack = getRackHandleNull(node);
        clusterModel.createRack(rack);
        BrokerCapacityInfo brokerCapacity;
        try {
            brokerCapacity = _brokerCapacityConfigResolver.capacityForBroker(rack, node.host(), node.id(), BROKER_CAPACITY_FETCH_TIMEOUT_MS, allowCapacityEstimation);
            LOG.debug("Capacity of broker {}: {}, (LogDir: {}, Cores: {}).", node.id(), brokerCapacity.capacity(), brokerCapacity.diskCapacityByLogDir(), brokerCapacity.numCpuCores());
            if (populateReplicaPlacementInfo && brokerCapacity.diskCapacityByLogDir() == null) {
                throw new IllegalStateException(String.format("Missing disk capacity information for logDirs on broker %d. " + "Are you trying to use a JBOD feature on a non-JBOD Kafka deployment?", node.id()));
            }
        } catch (TimeoutException | BrokerCapacityResolutionException e) {
            String errorMessage = String.format("Unable to retrieve capacity for broker %d. This may be caused by churn in " + "the cluster, please retry.", node.id());
            LOG.warn(errorMessage, e);
            throw e;
        }
        clusterModel.createBroker(rack, node.host(), node.id(), brokerCapacity, populateReplicaPlacementInfo);
    }
}
Also used : BrokerCapacityResolutionException(com.linkedin.kafka.cruisecontrol.exception.BrokerCapacityResolutionException) BrokerCapacityInfo(com.linkedin.kafka.cruisecontrol.config.BrokerCapacityInfo) Node(org.apache.kafka.common.Node) TimeoutException(java.util.concurrent.TimeoutException)

Example 2 with BrokerCapacityInfo

use of com.linkedin.kafka.cruisecontrol.config.BrokerCapacityInfo in project cruise-control by linkedin.

the class SortedReplicasTest method generateBroker.

private static Broker generateBroker(int numReplicas) {
    Rack rack = new Rack("rack");
    Host host = new Host("host", rack);
    Broker broker = new Broker(host, 0, new BrokerCapacityInfo(TestConstants.BROKER_CAPACITY), false);
    for (int i = 0; i < numReplicas; i++) {
        Replica r = new Replica(new TopicPartition(TOPIC0, i), broker, i % 3 == 0);
        broker.addReplica(r);
    }
    return broker;
}
Also used : BrokerCapacityInfo(com.linkedin.kafka.cruisecontrol.config.BrokerCapacityInfo) TopicPartition(org.apache.kafka.common.TopicPartition)

Example 3 with BrokerCapacityInfo

use of com.linkedin.kafka.cruisecontrol.config.BrokerCapacityInfo in project cruise-control by linkedin.

the class CruiseControlMetricsProcessorTest method testWithCpuCapacityEstimation.

@Test
public void testWithCpuCapacityEstimation() throws TimeoutException, BrokerCapacityResolutionException {
    Set<CruiseControlMetric> metrics = getCruiseControlMetrics();
    // All estimated.
    BrokerCapacityConfigResolver brokerCapacityConfigResolverAllEstimated = EasyMock.mock(BrokerCapacityConfigResolver.class);
    EasyMock.expect(brokerCapacityConfigResolverAllEstimated.capacityForBroker(EasyMock.anyString(), EasyMock.anyString(), EasyMock.anyInt(), EasyMock.anyLong(), EasyMock.eq(false))).andThrow(new BrokerCapacityResolutionException("Unable to resolve capacity.")).anyTimes();
    EasyMock.replay(brokerCapacityConfigResolverAllEstimated);
    CruiseControlMetricsProcessor processor = new CruiseControlMetricsProcessor(brokerCapacityConfigResolverAllEstimated, false);
    for (CruiseControlMetric cruiseControlMetric : metrics) {
        processor.addMetric(cruiseControlMetric);
    }
    Cluster cluster = getCluster();
    processor.process(cluster, TEST_PARTITIONS, MetricSampler.SamplingMode.ALL);
    for (Node node : cluster.nodes()) {
        assertNull(processor.cachedNumCoresByBroker().get(node.id()));
    }
    // Capacity resolver unable to retrieve broker capacity.
    BrokerCapacityConfigResolver brokerCapacityConfigResolverTimeout = EasyMock.mock(BrokerCapacityConfigResolver.class);
    EasyMock.expect(brokerCapacityConfigResolverTimeout.capacityForBroker(EasyMock.anyString(), EasyMock.anyString(), EasyMock.anyInt(), EasyMock.anyLong(), EasyMock.anyBoolean())).andThrow(new TimeoutException("Unable to resolve capacity.")).anyTimes();
    EasyMock.replay(brokerCapacityConfigResolverTimeout);
    processor = new CruiseControlMetricsProcessor(brokerCapacityConfigResolverTimeout, false);
    for (CruiseControlMetric cruiseControlMetric : metrics) {
        processor.addMetric(cruiseControlMetric);
    }
    cluster = getCluster();
    processor.process(cluster, TEST_PARTITIONS, MetricSampler.SamplingMode.ALL);
    for (Node node : cluster.nodes()) {
        assertNull(processor.cachedNumCoresByBroker().get(node.id()));
    }
    // Some estimated.
    BrokerCapacityConfigResolver brokerCapacityConfigResolverSomeEstimated = EasyMock.mock(BrokerCapacityConfigResolver.class);
    EasyMock.expect(brokerCapacityConfigResolverSomeEstimated.capacityForBroker(EasyMock.anyString(), EasyMock.anyString(), EasyMock.eq(BROKER_ID_1), EasyMock.anyLong(), EasyMock.anyBoolean())).andThrow(new TimeoutException("Unable to resolve capacity.")).anyTimes();
    EasyMock.expect(brokerCapacityConfigResolverSomeEstimated.capacityForBroker(EasyMock.anyString(), EasyMock.anyString(), EasyMock.eq(BROKER_ID_0), EasyMock.anyLong(), EasyMock.anyBoolean())).andReturn(new BrokerCapacityInfo(EMPTY_BROKER_CAPACITY, Collections.emptyMap(), MOCK_NUM_CPU_CORES)).anyTimes();
    EasyMock.replay(brokerCapacityConfigResolverSomeEstimated);
    processor = new CruiseControlMetricsProcessor(brokerCapacityConfigResolverSomeEstimated, false);
    for (CruiseControlMetric metric : metrics) {
        processor.addMetric(metric);
    }
    processor.process(cluster, TEST_PARTITIONS, MetricSampler.SamplingMode.ALL);
    assertEquals(MOCK_NUM_CPU_CORES, (short) processor.cachedNumCoresByBroker().get(BROKER_ID_0));
    assertNull(processor.cachedNumCoresByBroker().get(BROKER_ID_1));
    EasyMock.verify(brokerCapacityConfigResolverTimeout, brokerCapacityConfigResolverSomeEstimated, brokerCapacityConfigResolverAllEstimated);
}
Also used : BrokerCapacityResolutionException(com.linkedin.kafka.cruisecontrol.exception.BrokerCapacityResolutionException) CruiseControlMetric(com.linkedin.kafka.cruisecontrol.metricsreporter.metric.CruiseControlMetric) BrokerCapacityInfo(com.linkedin.kafka.cruisecontrol.config.BrokerCapacityInfo) BrokerCapacityConfigResolver(com.linkedin.kafka.cruisecontrol.config.BrokerCapacityConfigResolver) Node(org.apache.kafka.common.Node) Cluster(org.apache.kafka.common.Cluster) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.Test)

Example 4 with BrokerCapacityInfo

use of com.linkedin.kafka.cruisecontrol.config.BrokerCapacityInfo in project cruise-control by linkedin.

the class PreferredLeaderElectionGoalTest method createClusterModel.

private ClusterModelAndInfo createClusterModel(boolean skipClusterInfoGeneration, boolean populateDiskInfo) {
    ClusterModel clusterModel = new ClusterModel(new ModelGeneration(0, 0), 1.0);
    for (int i = 0; i < NUM_RACKS; i++) {
        clusterModel.createRack("r" + i);
    }
    BrokerCapacityInfo commonBrokerCapacityInfo = populateDiskInfo ? new BrokerCapacityInfo(TestConstants.BROKER_CAPACITY, null, TestConstants.DISK_CAPACITY) : new BrokerCapacityInfo(TestConstants.BROKER_CAPACITY);
    int i = 0;
    for (; i < 2; i++) {
        clusterModel.createBroker("r0", "h" + i, i, commonBrokerCapacityInfo, populateDiskInfo);
    }
    for (int j = 1; j < NUM_RACKS; j++, i++) {
        clusterModel.createBroker("r" + j, "h" + i, i, commonBrokerCapacityInfo, populateDiskInfo);
    }
    createReplicaAndSetLoad(clusterModel, "r0", 0, logdir(populateDiskInfo, 0, 0), T0P0, 0, true);
    createReplicaAndSetLoad(clusterModel, "r0", 1, logdir(populateDiskInfo, 0, 1), T0P1, 0, true);
    createReplicaAndSetLoad(clusterModel, "r1", 2, logdir(populateDiskInfo, 0, 2), T0P2, 0, true);
    createReplicaAndSetLoad(clusterModel, "r2", 3, logdir(populateDiskInfo, 0, 3), T1P0, 0, false);
    createReplicaAndSetLoad(clusterModel, "r3", 4, logdir(populateDiskInfo, 0, 4), T1P1, 0, false);
    createReplicaAndSetLoad(clusterModel, "r0", 0, logdir(populateDiskInfo, 0, 0), T1P2, 0, false);
    createReplicaAndSetLoad(clusterModel, "r0", 1, logdir(populateDiskInfo, 0, 1), T2P0, 0, false);
    createReplicaAndSetLoad(clusterModel, "r1", 2, logdir(populateDiskInfo, 0, 2), T2P1, 0, false);
    createReplicaAndSetLoad(clusterModel, "r2", 3, logdir(populateDiskInfo, 0, 3), T2P2, 0, false);
    createReplicaAndSetLoad(clusterModel, "r3", 4, logdir(populateDiskInfo, 1, 4), T0P0, 1, false);
    createReplicaAndSetLoad(clusterModel, "r1", 2, logdir(populateDiskInfo, 1, 2), T0P1, 1, false);
    createReplicaAndSetLoad(clusterModel, "r0", 0, logdir(populateDiskInfo, 1, 0), T0P2, 1, false);
    createReplicaAndSetLoad(clusterModel, "r0", 1, logdir(populateDiskInfo, 1, 1), T1P0, 1, true);
    createReplicaAndSetLoad(clusterModel, "r2", 3, logdir(populateDiskInfo, 1, 3), T1P1, 1, true);
    createReplicaAndSetLoad(clusterModel, "r3", 4, logdir(populateDiskInfo, 1, 4), T1P2, 1, true);
    createReplicaAndSetLoad(clusterModel, "r1", 2, logdir(populateDiskInfo, 1, 2), T2P0, 1, false);
    createReplicaAndSetLoad(clusterModel, "r0", 0, logdir(populateDiskInfo, 1, 0), T2P1, 1, false);
    createReplicaAndSetLoad(clusterModel, "r0", 1, logdir(populateDiskInfo, 1, 1), T2P2, 1, false);
    createReplicaAndSetLoad(clusterModel, "r2", 3, logdir(populateDiskInfo, 2, 3), T0P0, 2, false);
    createReplicaAndSetLoad(clusterModel, "r3", 4, logdir(populateDiskInfo, 2, 4), T0P1, 2, false);
    createReplicaAndSetLoad(clusterModel, "r2", 3, logdir(populateDiskInfo, 2, 3), T0P2, 2, false);
    createReplicaAndSetLoad(clusterModel, "r1", 2, logdir(populateDiskInfo, 2, 2), T1P0, 2, false);
    createReplicaAndSetLoad(clusterModel, "r0", 0, logdir(populateDiskInfo, 2, 0), T1P1, 2, false);
    createReplicaAndSetLoad(clusterModel, "r1", 2, logdir(populateDiskInfo, 2, 2), T1P2, 2, false);
    createReplicaAndSetLoad(clusterModel, "r3", 4, logdir(populateDiskInfo, 2, 4), T2P0, 2, true);
    createReplicaAndSetLoad(clusterModel, "r2", 3, logdir(populateDiskInfo, 2, 3), T2P1, 2, true);
    createReplicaAndSetLoad(clusterModel, "r3", 4, logdir(populateDiskInfo, 2, 4), T2P2, 2, true);
    Cluster cluster = null;
    if (!skipClusterInfoGeneration) {
        Node[] nodes = new Node[NUM_RACKS + 1];
        for (i = 0; i < NUM_RACKS + 1; i++) {
            nodes[i] = new Node(i, "h" + i, 100);
        }
        List<PartitionInfo> partitions = new ArrayList<>(9);
        // Make topic1 and topic2's partitions under replicated.
        partitions.add(new PartitionInfo(T0P0.topic(), T0P0.partition(), nodes[0], new Node[] { nodes[0], nodes[4], nodes[3] }, new Node[] { nodes[0], nodes[4], nodes[3] }));
        partitions.add(new PartitionInfo(T0P1.topic(), T0P1.partition(), nodes[1], new Node[] { nodes[1], nodes[2], nodes[4] }, new Node[] { nodes[1], nodes[2], nodes[4] }));
        partitions.add(new PartitionInfo(T0P2.topic(), T0P2.partition(), nodes[2], new Node[] { nodes[2], nodes[0], nodes[3] }, new Node[] { nodes[2], nodes[0], nodes[3] }));
        partitions.add(new PartitionInfo(T1P0.topic(), T1P0.partition(), nodes[1], new Node[] { nodes[1], nodes[3] }, new Node[] { nodes[1], nodes[3], nodes[2] }));
        partitions.add(new PartitionInfo(T1P1.topic(), T1P1.partition(), nodes[3], new Node[] { nodes[3], nodes[4] }, new Node[] { nodes[3], nodes[4], nodes[0] }));
        partitions.add(new PartitionInfo(T1P2.topic(), T1P2.partition(), nodes[4], new Node[] { nodes[4], nodes[2] }, new Node[] { nodes[4], nodes[2], nodes[0] }));
        partitions.add(new PartitionInfo(T2P0.topic(), T2P0.partition(), nodes[4], new Node[] { nodes[4], nodes[2] }, new Node[] { nodes[4], nodes[2], nodes[1] }));
        partitions.add(new PartitionInfo(T2P1.topic(), T2P1.partition(), nodes[3], new Node[] { nodes[3], nodes[0] }, new Node[] { nodes[3], nodes[0], nodes[2] }));
        partitions.add(new PartitionInfo(T2P2.topic(), T2P2.partition(), nodes[4], new Node[] { nodes[4], nodes[1] }, new Node[] { nodes[4], nodes[1], nodes[3] }));
        cluster = new Cluster("id", Arrays.asList(nodes), partitions, Collections.emptySet(), Collections.emptySet());
    }
    return new ClusterModelAndInfo(clusterModel, cluster);
}
Also used : ClusterModel(com.linkedin.kafka.cruisecontrol.model.ClusterModel) BrokerCapacityInfo(com.linkedin.kafka.cruisecontrol.config.BrokerCapacityInfo) ModelGeneration(com.linkedin.kafka.cruisecontrol.monitor.ModelGeneration) Node(org.apache.kafka.common.Node) ArrayList(java.util.ArrayList) Cluster(org.apache.kafka.common.Cluster) PartitionInfo(org.apache.kafka.common.PartitionInfo)

Example 5 with BrokerCapacityInfo

use of com.linkedin.kafka.cruisecontrol.config.BrokerCapacityInfo in project cruise-control by linkedin.

the class DeterministicCluster method getHomogeneousCluster.

/**
 * Creates a deterministic cluster with the given number of racks and the broker distribution.
 *
 * @param rackByBroker Racks by broker ids.
 * @param brokerCapacity Alive broker capacity.
 * @param diskCapacityByLogDir Disk capacity for each broker.
 * @return Cluster with the specified number of racks and broker distribution.
 */
public static ClusterModel getHomogeneousCluster(Map<Integer, Integer> rackByBroker, Map<Resource, Double> brokerCapacity, Map<String, Double> diskCapacityByLogDir) {
    // Sanity checks.
    if (rackByBroker.size() <= 0 || brokerCapacity.get(Resource.CPU) < 0 || brokerCapacity.get(Resource.DISK) < 0 || brokerCapacity.get(Resource.NW_IN) < 0 || brokerCapacity.get(Resource.NW_OUT) < 0) {
        throw new IllegalArgumentException("Deterministic cluster generation failed due to bad input.");
    }
    // Create cluster.
    ClusterModel cluster = new ClusterModel(new ModelGeneration(0, 0L), 1.0);
    // Create racks and add them to cluster.
    Set<Integer> racks = new HashSet<>();
    for (int rackId : rackByBroker.values()) {
        if (racks.add(rackId)) {
            cluster.createRack(Integer.toString(rackId));
        }
    }
    BrokerCapacityInfo commonBrokerCapacityInfo = new BrokerCapacityInfo(brokerCapacity, diskCapacityByLogDir);
    // Create brokers and assign a broker to each rack.
    rackByBroker.forEach((key, value) -> cluster.createBroker(value.toString(), Integer.toString(key), key, commonBrokerCapacityInfo, diskCapacityByLogDir != null));
    return cluster;
}
Also used : ClusterModel(com.linkedin.kafka.cruisecontrol.model.ClusterModel) BrokerCapacityInfo(com.linkedin.kafka.cruisecontrol.config.BrokerCapacityInfo) ModelGeneration(com.linkedin.kafka.cruisecontrol.monitor.ModelGeneration) HashSet(java.util.HashSet)

Aggregations

BrokerCapacityInfo (com.linkedin.kafka.cruisecontrol.config.BrokerCapacityInfo)10 ClusterModel (com.linkedin.kafka.cruisecontrol.model.ClusterModel)4 ModelGeneration (com.linkedin.kafka.cruisecontrol.monitor.ModelGeneration)4 Node (org.apache.kafka.common.Node)4 BrokerCapacityConfigResolver (com.linkedin.kafka.cruisecontrol.config.BrokerCapacityConfigResolver)3 BrokerCapacityResolutionException (com.linkedin.kafka.cruisecontrol.exception.BrokerCapacityResolutionException)3 TimeoutException (java.util.concurrent.TimeoutException)3 Cluster (org.apache.kafka.common.Cluster)3 CruiseControlMetric (com.linkedin.kafka.cruisecontrol.metricsreporter.metric.CruiseControlMetric)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 PartitionInfo (org.apache.kafka.common.PartitionInfo)2 TopicPartition (org.apache.kafka.common.TopicPartition)2 Test (org.junit.Test)2 AggregatedMetricValues (com.linkedin.cruisecontrol.monitor.sampling.aggregator.AggregatedMetricValues)1 BalancingConstraint (com.linkedin.kafka.cruisecontrol.analyzer.BalancingConstraint)1 Resource (com.linkedin.kafka.cruisecontrol.common.Resource)1 Broker (com.linkedin.kafka.cruisecontrol.model.Broker)1 Partition (com.linkedin.kafka.cruisecontrol.model.Partition)1