Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Merge branch master into new_mainline
Browse files Browse the repository at this point in the history
Changes for 1 package (OpenDistroPerformanceAnalyzerEngine), pushed in snapshot...

  https://code.amazon.com/snapshots/partsrut/2020-08-08T02-49-04

Changes for OpenDistroPerformanceAnalyzerEngine package:

0194f9f Fix failing reaction wheel tests
bfdb93d Merge remote-tracking branch 'upstream/master'
e03a120 Use StringUtils instead of NumberUtils to check timestamp string (#360)
79841f2 Expose queue rejection time period setting in rca.conf (#356)
f9dfda5 Implement isMuted method in DummyAction (#355)
7ede0b9 Reader changes for dynamic enable/disable of RCA graph components (#325)
ee58207 Fix bug in publisher to support cool off period on a per node basis (#351)

cr https://code.amazon.com/reviews/CR-31344155
  • Loading branch information
sruti1312 committed Aug 8, 2020
2 parents 41b3ead + 0194f9f commit 2049475
Show file tree
Hide file tree
Showing 51 changed files with 1,442 additions and 199 deletions.
5 changes: 5 additions & 0 deletions pa_config/rca.conf
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
"promotion-rate-mb-per-second" : 500,
"young-gen-gc-time-ms-per-second" : 400
},
"queue-rejection-rca": {
"rejection-time-period-in-seconds" : 300
},
//hot shard rca
"hot-shard-rca": {
"cpu-utilization" : 0.01,
Expand Down Expand Up @@ -85,6 +88,8 @@
"NodeTemperatureRca",
"ClusterTemperatureRca"
],
"muted-deciders": [],
"muted-actions": [],

"decider-config-settings": {
// cache decider - Needs to be updated as per the performance test results
Expand Down
5 changes: 5 additions & 0 deletions pa_config/rca_idle_master.conf
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
"promotion-rate-mb-per-second" : 500,
"young-gen-gc-time-ms-per-second" : 400
},
"queue-rejection-rca": {
"rejection-time-period-in-seconds" : 300
},
//unbalanced node rca
"hot-node-cluster-rca": {
"unbalanced-resource-percentage" : 0.3,
Expand Down Expand Up @@ -96,6 +99,8 @@
"NodeTemperatureRca",
"ClusterTemperatureRca"
],
"muted-deciders": [],
"muted-actions": [],

"decider-config-settings": {
// cache decider - Needs to be updated as per the performance test results
Expand Down
5 changes: 5 additions & 0 deletions pa_config/rca_master.conf
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
"promotion-rate-mb-per-second" : 500,
"young-gen-gc-time-ms-per-second" : 400
},
"queue-rejection-rca": {
"rejection-time-period-in-seconds" : 300
},
//unbalanced node rca
"hot-node-cluster-rca": {
"unbalanced-resource-percentage" : 0.3,
Expand Down Expand Up @@ -96,6 +99,8 @@
"NodeTemperatureRca",
"ClusterTemperatureRca"
],
"muted-deciders": [],
"muted-actions": [],

"decider-config-settings": {
// cache decider - Needs to be updated as per the performance test results
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.common.collect.ImmutableSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -39,10 +40,12 @@ public class AppContext {
// initiate a node config cache within each AppContext space
// to store node config settings from ES
private final NodeConfigCache nodeConfigCache;
private volatile Set<String> mutedActions;

public AppContext() {
this.clusterDetailsEventProcessor = null;
this.nodeConfigCache = new NodeConfigCache();
this.mutedActions = ImmutableSet.of();
}

public AppContext(AppContext other) {
Expand Down Expand Up @@ -123,4 +126,12 @@ public InstanceDetails getInstanceById(InstanceDetails.Id instanceIdKey) {
.findFirst()
.orElse(new InstanceDetails(AllMetrics.NodeRole.UNKNOWN));
}

public boolean isActionMuted(final String action) {
return this.mutedActions.contains(action);
}

public void updateMutedActions(final Set<String> mutedActions) {
this.mutedActions = ImmutableSet.copyOf(mutedActions);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.amazon.opendistro.elasticsearch.performanceanalyzer.config.overrides;

import com.amazon.opendistro.elasticsearch.performanceanalyzer.PerformanceAnalyzerApp;
import com.amazon.opendistro.elasticsearch.performanceanalyzer.rca.framework.core.RcaConf;
import com.amazon.opendistro.elasticsearch.performanceanalyzer.reader.ClusterDetailsEventProcessor;
import com.google.common.annotations.VisibleForTesting;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
* Class the manages applying the various overrides for RCAs, deciders, and action nodes as
* written by the NodeDetails collector and read by the {@link ClusterDetailsEventProcessor}
*/
public class ConfigOverridesApplier {

private static final Logger LOG = LogManager.getLogger(ConfigOverridesApplier.class);
private long lastAppliedTimestamp;

public void applyOverride(final String overridesJson, final String lastUpdatedTimestampString) {
if (!valid(overridesJson, lastUpdatedTimestampString)) {
LOG.warn("Received invalid overrides or timestamp. Overrides json: {}, last updated "
+ "timestamp: {}", overridesJson, lastAppliedTimestamp);
return;
}

try {
long lastUpdatedTimestamp = Long.parseLong(lastUpdatedTimestampString);
LOG.debug("Last updated(writer): {}, Last applied(reader): {}", lastUpdatedTimestamp,
lastAppliedTimestamp);
if (lastUpdatedTimestamp > lastAppliedTimestamp) {
apply(ConfigOverridesHelper.deserialize(overridesJson));
} else {
LOG.debug("Not applying override. Last updated timestamp {} is behind last applied "
+ "timestamp {}", lastUpdatedTimestamp, lastAppliedTimestamp);
}
} catch (IOException ioe) {
LOG.error("Unable to deserialize overrides JSON:" + overridesJson, ioe);
} catch (NumberFormatException nfe) {
LOG.error("Unable to parse the lastUpdatedTimestamp {} string as a number.",
lastUpdatedTimestampString, nfe);
}
}

private void apply(final ConfigOverrides overrides) {
if (PerformanceAnalyzerApp.getRcaController() != null && PerformanceAnalyzerApp.getRcaController().isRcaEnabled()) {
LOG.info("Applying overrides: {}", overrides.getEnable().getRcas());
RcaConf rcaConf = PerformanceAnalyzerApp.getRcaController().getRcaConf();
if (rcaConf != null) {
Set<String> currentMutedRcaSet = new HashSet<>(rcaConf.getMutedRcaList());
Set<String> currentMutedDeciderSet = new HashSet<>(rcaConf.getMutedDeciderList());
Set<String> currentMutedActionSet = new HashSet<>(rcaConf.getMutedActionList());
// check and remove any nodes that are in the disabled list that were enabled just now.
if (overrides.getEnable() != null) {
if (overrides.getEnable().getRcas() != null) {
currentMutedRcaSet.removeAll(overrides.getEnable().getRcas());
}
if (overrides.getEnable().getDeciders() != null) {
currentMutedDeciderSet.removeAll(overrides.getEnable().getDeciders());
}
if (overrides.getEnable().getActions() != null) {
currentMutedActionSet.removeAll(overrides.getEnable().getActions());
}
}

// union the remaining already disabled nodes with the new set of disabled nodes.
if (overrides.getDisable() != null) {
if (overrides.getDisable().getRcas() != null) {
currentMutedRcaSet.addAll(overrides.getDisable().getRcas());
}
if (overrides.getDisable().getDeciders() != null) {
currentMutedDeciderSet.addAll(overrides.getDisable().getDeciders());
}
if (overrides.getDisable().getActions() != null) {
currentMutedActionSet.addAll(overrides.getDisable().getActions());
}
}

LOG.info("New set of muted rcas: {}", currentMutedRcaSet);
LOG.info("New set of muted deciders: {}", currentMutedDeciderSet);
LOG.info("New set of muted actions: {}", currentMutedActionSet);
boolean updateSuccess = rcaConf.updateAllRcaConfFiles(currentMutedRcaSet,
currentMutedDeciderSet, currentMutedActionSet);
if (updateSuccess) {
this.lastAppliedTimestamp = System.currentTimeMillis();
}
}
}
}

private boolean valid(final String overridesJson, final String timestamp) {
if (overridesJson == null || timestamp == null) {
return false;
}

if (overridesJson.isEmpty() || timestamp.isEmpty()) {
return false;
}

return StringUtils.isNumeric(timestamp);
}

@VisibleForTesting
public long getLastAppliedTimestamp() {
return lastAppliedTimestamp;
}

@VisibleForTesting
public void setLastAppliedTimestamp(final long lastAppliedTimestamp) {
this.lastAppliedTimestamp = lastAppliedTimestamp;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,31 @@

package com.amazon.opendistro.elasticsearch.performanceanalyzer.config.overrides;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.annotations.VisibleForTesting;

/**
* Class responsible for holding the latest config overrides across the cluster.
*/
public class ConfigOverridesWrapper {

private volatile ConfigOverrides currentClusterConfigOverrides;
private volatile long lastUpdatedTimestamp;
private final ObjectMapper mapper;

public ConfigOverridesWrapper() {
this(new ObjectMapper());
}

/**
* Ctor used only for unit test purposes.
* @param mapper The object mapper instance.
*/
@VisibleForTesting
public ConfigOverridesWrapper(final ObjectMapper mapper) {
this.currentClusterConfigOverrides = new ConfigOverrides();
this.mapper = mapper;
}

public ConfigOverrides getCurrentClusterConfigOverrides() {
return currentClusterConfigOverrides;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package com.amazon.opendistro.elasticsearch.performanceanalyzer.decisionmaker.actions;

import com.amazon.opendistro.elasticsearch.performanceanalyzer.rca.framework.core.Stats;
import com.amazon.opendistro.elasticsearch.performanceanalyzer.rca.store.rca.cluster.NodeKey;

import java.util.List;
Expand Down Expand Up @@ -44,4 +45,7 @@ public interface Action {

/** Returns a summary for the configured action */
String summary();

/** Returns if this action is explicitly muted through configuration */
boolean isMuted();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package com.amazon.opendistro.elasticsearch.performanceanalyzer.decisionmaker.actions;

import com.amazon.opendistro.elasticsearch.performanceanalyzer.rca.store.rca.cluster.NodeKey;
import com.google.common.annotations.VisibleForTesting;
import java.time.Clock;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.builder.HashCodeBuilder;

/**
* Detect whether an action has passed its cool off period or not. Due to the heterogeneous nature of
* Decision Maker framework, this CoolOffDetector needs to keep track of the latest execution timestamp
* of the most recent actions on each node. An action is identified as "Cooled Off" only if the cool off
* period of the action has elapsed on all impacted nodes of this action
*/
public class CoolOffDetector {
private Map<NodeActionKey, Long> actionToExecutionTime;
private long initTime;
private Clock clock;

public CoolOffDetector() {
this.actionToExecutionTime = new HashMap<>();
this.clock = Clock.systemUTC();
this.initTime = clock.millis();
}

/**
* Returns true if a given {@link Action}'s last execution time was >= {@link Action#coolOffPeriodInMillis()} ago
*
* <p>If this Publisher has never executed the action, the last execution time is defined as the time when the
* CoolOffDetector object was constructed.
* @param action The {@link Action} to test
* @return true if action is cooled off on all impacted nodes of this action
*/
public boolean isCooledOff(Action action) {
for (NodeKey esNode : action.impactedNodes()) {
boolean cooledOff = checkCooledOff(action.name(), esNode, action.coolOffPeriodInMillis());
if (!cooledOff) {
return false;
}
}
return true;
}

/**
* record the timestamp when this action is published
* @param action action to be recorded
*/
public void recordAction(Action action) {
long currentTimestamp = clock.millis();
for (NodeKey esNode : action.impactedNodes()) {
NodeActionKey nodeActionKey = new NodeActionKey(action.name(), esNode);
actionToExecutionTime.put(nodeActionKey, currentTimestamp);
}
}

private boolean checkCooledOff(String actionName, NodeKey esNode, long coolOffPeriod) {
long currentTimestamp = clock.millis();
NodeActionKey nodeActionKey = new NodeActionKey(actionName, esNode);
long lastExecution = actionToExecutionTime.getOrDefault(nodeActionKey, initTime);
long elapsed = currentTimestamp - lastExecution;
return elapsed >= coolOffPeriod;
}

@VisibleForTesting
public void setClock(Clock clock) {
this.clock = clock;
}

@VisibleForTesting
public void setInitTime(long initTime) {
this.initTime = initTime;
}

/**
* define a hash key class for cool off map.
*/
private static class NodeActionKey {
private final NodeKey nodeKey;
private final String actionName;

public NodeActionKey(final String actionName, final NodeKey nodeKey) {
this.nodeKey = nodeKey;
this.actionName = actionName;
}

public NodeKey getNodeKey() {
return this.nodeKey;
}

public String getActionName() {
return this.actionName;
}

@Override
public boolean equals(Object obj) {
if (obj instanceof CoolOffDetector.NodeActionKey) {
CoolOffDetector.NodeActionKey key = (CoolOffDetector.NodeActionKey)obj;
return nodeKey.equals(key.getNodeKey()) && actionName.equals(key.getActionName());
}
return false;
}

@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(nodeKey.hashCode())
.append(actionName.hashCode())
.toHashCode();
}
}
}
Loading

0 comments on commit 2049475

Please sign in to comment.