use of com.linkedin.kafka.cruisecontrol.monitor.sampling.holder.BrokerEntity in project cruise-control by linkedin.
the class SlowBrokers method configure.
@Override
public void configure(Map<String, ?> configs) {
super.configure(configs);
KafkaCruiseControl kafkaCruiseControl = extractKafkaCruiseControlObjectFromConfig(configs, KafkaAnomalyType.METRIC_ANOMALY);
if (_fixable) {
Boolean removeSlowBroker = (Boolean) configs.get(SlowBrokerFinder.REMOVE_SLOW_BROKER_CONFIG);
if (removeSlowBroker == null) {
throw new IllegalArgumentException(String.format("Missing %s for slow broker anomaly.", SlowBrokerFinder.REMOVE_SLOW_BROKER_CONFIG));
}
KafkaCruiseControlConfig config = kafkaCruiseControl.config();
boolean allowCapacityEstimation = config.getBoolean(ANOMALY_DETECTION_ALLOW_CAPACITY_ESTIMATION_CONFIG);
boolean excludeRecentlyDemotedBrokers = config.getBoolean(SELF_HEALING_EXCLUDE_RECENTLY_DEMOTED_BROKERS_CONFIG);
boolean excludeRecentlyRemovedBrokers = config.getBoolean(SELF_HEALING_EXCLUDE_RECENTLY_REMOVED_BROKERS_CONFIG);
if (removeSlowBroker) {
_removeBrokersRunnable = new RemoveBrokersRunnable(kafkaCruiseControl, _brokerEntitiesWithDetectionTimeMs.keySet().stream().mapToInt(BrokerEntity::brokerId).boxed().collect(Collectors.toSet()), getSelfHealingGoalNames(config), allowCapacityEstimation, excludeRecentlyDemotedBrokers, excludeRecentlyRemovedBrokers, _anomalyId.toString(), reasonSupplier(), stopOngoingExecution());
} else {
_demoteBrokerRunnable = new DemoteBrokerRunnable(kafkaCruiseControl, _brokerEntitiesWithDetectionTimeMs.keySet().stream().mapToInt(BrokerEntity::brokerId).boxed().collect(Collectors.toSet()), allowCapacityEstimation, excludeRecentlyDemotedBrokers, _anomalyId.toString(), reasonSupplier(), stopOngoingExecution());
}
}
}
use of com.linkedin.kafka.cruisecontrol.monitor.sampling.holder.BrokerEntity in project cruise-control by linkedin.
the class SlowBrokerFinder method detectMetricAnomalies.
private Set<BrokerEntity> detectMetricAnomalies(Map<BrokerEntity, ValuesAndExtrapolations> metricsHistoryByBroker, Map<BrokerEntity, ValuesAndExtrapolations> currentMetricsByBroker) {
// Preprocess raw metrics to get the metrics of interest for each broker.
Map<BrokerEntity, List<Double>> historicalLogFlushTimeMetricValues = new HashMap<>();
Map<BrokerEntity, Double> currentLogFlushTimeMetricValues = new HashMap<>();
Map<BrokerEntity, List<Double>> historicalPerByteLogFlushTimeMetricValues = new HashMap<>();
Map<BrokerEntity, Double> currentPerByteLogFlushTimeMetricValues = new HashMap<>();
Set<Integer> skippedBrokers = new HashSet<>();
for (Map.Entry<BrokerEntity, ValuesAndExtrapolations> entry : currentMetricsByBroker.entrySet()) {
BrokerEntity broker = entry.getKey();
if (!brokerHasNegligibleTraffic(broker, entry.getValue().metricValues())) {
collectLogFlushTimeMetric(broker, metricsHistoryByBroker.get(broker), entry.getValue(), historicalLogFlushTimeMetricValues, currentLogFlushTimeMetricValues);
collectPerByteLogFlushTimeMetric(broker, metricsHistoryByBroker.get(broker), entry.getValue(), historicalPerByteLogFlushTimeMetricValues, currentPerByteLogFlushTimeMetricValues);
} else {
skippedBrokers.add(broker.brokerId());
}
}
if (!skippedBrokers.isEmpty()) {
LOG.info("Skip slowness check for brokers {} because they serve negligible traffic.", skippedBrokers);
}
Set<BrokerEntity> detectedMetricAnomalies = getMetricAnomalies(historicalLogFlushTimeMetricValues, currentLogFlushTimeMetricValues);
detectedMetricAnomalies.retainAll(getMetricAnomalies(historicalPerByteLogFlushTimeMetricValues, currentPerByteLogFlushTimeMetricValues));
detectedMetricAnomalies.retainAll(getLogFlushTimeMetricAnomaliesFromValue(currentLogFlushTimeMetricValues));
return detectedMetricAnomalies;
}
use of com.linkedin.kafka.cruisecontrol.monitor.sampling.holder.BrokerEntity in project cruise-control by linkedin.
the class ConcurrencyAdjusterTest method createCurrentMetrics.
/**
* Create current load snapshot for brokers.
* @param metricValueByIdPerBroker A set of metrics with corresponding load value per broker.
* @return The load for the brokers.
*/
public static Map<BrokerEntity, ValuesAndExtrapolations> createCurrentMetrics(List<Map<Short, Double>> metricValueByIdPerBroker) {
Map<BrokerEntity, ValuesAndExtrapolations> currentMetrics = new HashMap<>();
for (int i = 0; i < metricValueByIdPerBroker.size(); i++) {
Map<Short, MetricValues> valuesByMetricId = new HashMap<>();
for (Map.Entry<Short, Double> entry : metricValueByIdPerBroker.get(i).entrySet()) {
MetricValues currentMetricValues = new MetricValues(1);
double[] values = new double[] { entry.getValue() };
currentMetricValues.add(values);
valuesByMetricId.put(entry.getKey(), currentMetricValues);
}
AggregatedMetricValues aggregatedMetricValues = new AggregatedMetricValues(valuesByMetricId);
ValuesAndExtrapolations currentValuesAndExtrapolations = new ValuesAndExtrapolations(aggregatedMetricValues, null);
List<Long> windows = new ArrayList<>(1);
windows.add(1L);
currentValuesAndExtrapolations.setWindows(windows);
currentMetrics.put(new BrokerEntity(ExecutorTest.class.getSimpleName(), i), currentValuesAndExtrapolations);
}
return currentMetrics;
}
use of com.linkedin.kafka.cruisecontrol.monitor.sampling.holder.BrokerEntity in project cruise-control by linkedin.
the class ExecutionUtils method withinConcurrencyAdjusterLimit.
/**
* Check whether the current metrics are within the limit specified by {@link #CONCURRENCY_ADJUSTER_LIMIT_BY_METRIC_NAME}.
* Package private for unit tests.
*
* @param currentMetricsByBroker Current metrics by broker.
* @return {@code true} if all brokers are within the limit specified by {@link #CONCURRENCY_ADJUSTER_LIMIT_BY_METRIC_NAME},
* {@code false} otherwise.
*/
static boolean withinConcurrencyAdjusterLimit(Map<BrokerEntity, ValuesAndExtrapolations> currentMetricsByBroker) {
boolean withinLimit = true;
Set<BrokerEntity> brokersWithNoMetrics = new HashSet<>();
Map<String, StringBuilder> overLimitDetailsByMetricName = new HashMap<>();
for (String metricName : CONCURRENCY_ADJUSTER_LIMIT_BY_METRIC_NAME.keySet()) {
overLimitDetailsByMetricName.put(metricName, new StringBuilder());
}
for (Map.Entry<BrokerEntity, ValuesAndExtrapolations> entry : currentMetricsByBroker.entrySet()) {
BrokerEntity broker = entry.getKey();
ValuesAndExtrapolations current = entry.getValue();
if (current == null) {
brokersWithNoMetrics.add(broker);
continue;
}
// Check whether the broker is within the acceptable limit for the relevant metrics. If not, collect details.
for (Short metricId : current.metricValues().metricIds()) {
String metricName = toMetricName(metricId);
Double limit = CONCURRENCY_ADJUSTER_LIMIT_BY_METRIC_NAME.get(metricName);
if (limit != null) {
double metricValue = current.metricValues().valuesFor(metricId).latest();
if (metricValue > limit) {
overLimitDetailsByMetricName.get(metricName).append(String.format("%d(%.2f) ", broker.brokerId(), metricValue));
}
}
}
}
for (Map.Entry<String, StringBuilder> entry : overLimitDetailsByMetricName.entrySet()) {
StringBuilder brokersWithValues = entry.getValue();
if (brokersWithValues.length() > 0) {
LOG.info("{} is over the acceptable limit for brokers with values: {}.", entry.getKey(), brokersWithValues);
withinLimit = false;
}
}
if (!brokersWithNoMetrics.isEmpty()) {
LOG.warn("Assuming {} are over the acceptable limit as no broker metrics exist to verify.", brokersWithNoMetrics);
withinLimit = false;
}
return withinLimit;
}
use of com.linkedin.kafka.cruisecontrol.monitor.sampling.holder.BrokerEntity in project cruise-control by linkedin.
the class LoadMonitor method brokerMetrics.
/**
* @return All the available broker level metrics. Null is returned if nothing is available.
*/
public MetricSampleAggregationResult<String, BrokerEntity> brokerMetrics() {
List<Node> nodes = kafkaCluster().nodes();
Set<BrokerEntity> brokerEntities = new HashSet<>();
for (Node node : nodes) {
brokerEntities.add(new BrokerEntity(node.host(), node.id()));
}
return _brokerMetricSampleAggregator.aggregate(brokerEntities);
}
Aggregations