summaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@gmail.com>2021-03-11 12:34:00 +0100
committerJon Bratseth <bratseth@gmail.com>2021-03-11 12:34:00 +0100
commite87e4ac7b5dcaff7483e90cb4b6b610559ae2c06 (patch)
tree39d7aace5023ef22175e58fae4b07d5e0409190c /node-repository
parentb310bcb0d382dcb2f5c481902772c591a77197d8 (diff)
Lock less
- Only lock the application if a new autoscaling target is produced or cluster information should be updated. - Only create a maintenance deployment if we should redeploy.
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java1
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ResourceTarget.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java56
3 files changed, 34 insertions, 25 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java
index bddbcf43bd0..69d7cec4007 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Cluster.java
@@ -125,6 +125,7 @@ public class Cluster {
}
public Cluster withAutoscalingStatus(String autoscalingStatus) {
+ if (autoscalingStatus.equals(this.autoscalingStatus)) return this;
return new Cluster(id, exclusive, min, max, suggested, target, scalingEvents, autoscalingStatus);
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ResourceTarget.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ResourceTarget.java
index d2bfecfcdae..f29181b8343 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ResourceTarget.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/autoscale/ResourceTarget.java
@@ -49,7 +49,7 @@ public class ResourceTarget {
}
/** Create a target of achieving ideal load given a current load */
- public static ResourceTarget idealLoad(ClusterTimeseries clusterTimeseries,
+ public static ResourceTarget idealLoad(ClusterTimeseries clusterTimeseries,
ClusterNodesTimeseries clusterNodesTimeseries,
AllocatableClusterResources current,
Application application) {
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java
index 9d910df01d9..9df6af4d02a 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java
@@ -62,34 +62,42 @@ public class AutoscalingMaintainer extends NodeRepositoryMaintainer {
}
private void autoscale(ApplicationId application, List<Node> applicationNodes) {
- try (MaintenanceDeployment deployment = new MaintenanceDeployment(application, deployer, metric, nodeRepository())) {
- if ( ! deployment.isValid()) return;
- nodesByCluster(applicationNodes).forEach((clusterId, clusterNodes) -> autoscale(application, clusterId, NodeList.copyOf(clusterNodes), deployment));
- }
+ nodesByCluster(applicationNodes).forEach((clusterId, clusterNodes) -> autoscale(application, clusterId, NodeList.copyOf(clusterNodes)));
}
- private void autoscale(ApplicationId applicationId,
- ClusterSpec.Id clusterId,
- NodeList clusterNodes,
- MaintenanceDeployment deployment) {
- Application application = nodeRepository().applications().get(applicationId).orElse(Application.empty(applicationId));
- if (application.cluster(clusterId).isEmpty()) return;
- Cluster cluster = application.cluster(clusterId).get();
- cluster = updateCompletion(cluster, clusterNodes);
- var advice = autoscaler.autoscale(application, cluster, clusterNodes);
- cluster = cluster.withAutoscalingStatus(advice.reason());
-
- if (advice.isPresent() && !cluster.targetResources().equals(advice.target())) { // autoscale
- cluster = cluster.withTarget(advice.target());
- applications().put(application.with(cluster), deployment.applicationLock().get());
- if (advice.target().isPresent()) {
- logAutoscaling(advice.target().get(), applicationId, cluster, clusterNodes);
- deployment.activate();
+ private void autoscale(ApplicationId applicationId, ClusterSpec.Id clusterId, NodeList clusterNodes) {
+ Optional<Application> application = nodeRepository().applications().get(applicationId);
+ if (application.isEmpty()) return;
+ Optional<Cluster> cluster = application.get().cluster(clusterId);
+ if (cluster.isEmpty()) return;
+
+ Cluster updatedCluster = updateCompletion(cluster.get(), clusterNodes);
+ var advice = autoscaler.autoscale(application.get(), updatedCluster, clusterNodes);
+
+ // Lock and write if there are state updates and/or we should autoscale now
+ if (advice.isPresent() && !cluster.get().targetResources().equals(advice.target()) ||
+ (updatedCluster != cluster.get() || !advice.reason().equals(cluster.get().autoscalingStatus()))) {
+ try (var lock = nodeRepository().nodes().lock(applicationId)) {
+ application = nodeRepository().applications().get(applicationId);
+ if (application.isEmpty()) return;
+ cluster = application.get().cluster(clusterId);
+ if (cluster.isEmpty()) return;
+
+ // 1. Update cluster info
+ updatedCluster = updateCompletion(cluster.get(), clusterNodes)
+ .withAutoscalingStatus(advice.reason())
+ .withTarget(advice.target());
+ applications().put(application.get().with(updatedCluster), lock);
+ if (advice.isPresent() && advice.target().isPresent() && !cluster.get().targetResources().equals(advice.target())) {
+ // 2. Also autoscale
+ logAutoscaling(advice.target().get(), applicationId, updatedCluster, clusterNodes);
+ try (MaintenanceDeployment deployment = new MaintenanceDeployment(applicationId, deployer, metric, nodeRepository())) {
+ if (deployment.isValid())
+ deployment.activate();
+ }
+ }
}
}
- else { // store cluster update
- applications().put(application.with(cluster), deployment.applicationLock().get());
- }
}
private Applications applications() {