summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortoby <smorgrav@yahoo-inc.com>2017-10-12 12:07:13 +0200
committertoby <smorgrav@yahoo-inc.com>2017-10-12 12:07:13 +0200
commit039e81aafd0fa4ad7eac5ff17a514b5d5362d4be (patch)
treef8d405419f5014ca05e6080ef86f04e48d8621f7
parent7b7beb1a88e78bb2747d98ce52c74cb56225d1be (diff)
Add more flavor info and redefine cluster tco and waste
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterCost.java6
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterInfo.java39
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainer.java24
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java2
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java6
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainerTest.java2
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java2
7 files changed, 68 insertions, 13 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterCost.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterCost.java
index b337f85bd6c..59200af2594 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterCost.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterCost.java
@@ -41,8 +41,10 @@ public class ClusterCost {
this.targetUtilization = new ClusterUtilization(0.7,0.2, 0.7, 0.3);
this.resultUtilization = calculateResultUtilization(systemUtilization, targetUtilization);
- this.tco = clusterInfo.getCost() * Math.min(1, this.resultUtilization.getMaxUtilization());
- this.waste = clusterInfo.getCost() - tco;
+ this.tco = clusterInfo.getHostnames().size() * clusterInfo.getFlavorCost();
+
+ double unusedUtilization = 1 - Math.max(1, systemUtilization.getMaxUtilization());
+ this.waste = tco * unusedUtilization;
}
/** @return The TCO in dollars for this cluster (node tco * nodes) */
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterInfo.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterInfo.java
index cb39177c811..40fc57acdc8 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterInfo.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/application/ClusterInfo.java
@@ -9,31 +9,62 @@ import java.util.List;
* Value object of static cluster information, in particular the TCO
* of the hardware used for this cluster.
*
+ * Some duplication/flattening of flavor info is done to simplify client usage.
+ *
* @author smorgrav
*/
public class ClusterInfo {
private final String flavor;
- private final int cost;
+ private final double flavorCPU;
+ private final double flavorMem;
+ private final double flavorDisk;
+ private final int flavorCost;
private final ClusterSpec.Type clusterType;
private final List<String> hostnames;
- public ClusterInfo(String flavor, int cost, ClusterSpec.Type clusterType, List<String> hostnames) {
+ /**
+ * @param flavor The name of the flavor eg. 'C-2B/24/500'
+ * @param flavorCost The cost of one node in dollars
+ * @param flavorCPU The number of cpu cores granted
+ * @param flavorMem The memory granted in Gb
+ * @param flavorDisk The disk size granted in Gb
+ * @param clusterType The vespa cluster type e.g 'container' or 'content'
+ * @param hostnames All hostnames in this cluster
+ */
+ public ClusterInfo(String flavor, int flavorCost, double flavorCPU, double flavorMem,
+ double flavorDisk, ClusterSpec.Type clusterType, List<String> hostnames) {
this.flavor = flavor;
- this.cost = cost;
+ this.flavorCost = flavorCost;
+ this.flavorCPU = flavorCPU;
+ this.flavorMem = flavorMem;
+ this.flavorDisk = flavorDisk;
this.clusterType = clusterType;
this.hostnames = hostnames;
}
+ /** @return The name of the flavor eg. 'C-2B/24/500' */
public String getFlavor() {
return flavor;
}
- public int getCost() { return cost; }
+ /** @return The cost of one node in dollars */
+ public int getFlavorCost() { return flavorCost; }
+
+ /** @return The disk size granted in Gb */
+ public double getFlavorDisk() { return flavorDisk; }
+
+ /** @return The number of cpu cores granted */
+ public double getFlavorCPU() { return flavorCPU; }
+
+ /** @return The memory granted in Gb */
+ public double getFlavorMem() { return flavorMem; }
+ /** @return The vespa cluster type e.g 'container' or 'content' */
public ClusterSpec.Type getClusterType() {
return clusterType;
}
+ /** @return All hostnames in this cluster */
public List<String> getHostnames() {
return hostnames;
}
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainer.java
index 8f5db8832fa..c807a7f0586 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainer.java
@@ -2,6 +2,8 @@
package com.yahoo.vespa.hosted.controller.maintenance;
import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.curator.Lock;
import com.yahoo.vespa.hosted.controller.Application;
import com.yahoo.vespa.hosted.controller.Controller;
@@ -15,6 +17,7 @@ import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -38,7 +41,7 @@ public class ClusterInfoMaintainer extends Maintainer {
return node.membership.clusterId;
}
- private Map<ClusterSpec.Id, ClusterInfo> getClusterInfo(NodeList nodes) {
+ private Map<ClusterSpec.Id, ClusterInfo> getClusterInfo(NodeList nodes, Zone zone) {
Map<ClusterSpec.Id, ClusterInfo> infoMap = new HashMap<>();
// Group nodes by clusterid
@@ -53,9 +56,24 @@ public class ClusterInfoMaintainer extends Maintainer {
//Assume they are all equal and use first node as a representatitve for the cluster
NodeList.Node node = clusterNodes.get(0);
+ // Extract flavor info
+ double cpu = 0;
+ double mem = 0;
+ double disk = 0;
+ if (zone.nodeFlavors().isPresent()) {
+ Optional<Flavor> flavorOptional = zone.nodeFlavors().get().getFlavor(node.flavor);
+ if ((flavorOptional.isPresent())) {
+ Flavor flavor = flavorOptional.get();
+ cpu = flavor.getMinCpuCores();
+ mem = flavor.getMinMainMemoryAvailableGb();
+ disk = flavor.getMinMainMemoryAvailableGb();
+ }
+ }
+
// Add to map
List<String> hostnames = clusterNodes.stream().map(node1 -> node1.hostname).collect(Collectors.toList());
- ClusterInfo inf = new ClusterInfo(node.flavor, node.cost, ClusterSpec.Type.from(node.membership.clusterType), hostnames);
+ ClusterInfo inf = new ClusterInfo(node.flavor, node.cost, cpu, mem, disk,
+ ClusterSpec.Type.from(node.membership.clusterType), hostnames);
infoMap.put(new ClusterSpec.Id(id), inf);
}
@@ -71,7 +89,7 @@ public class ClusterInfoMaintainer extends Maintainer {
DeploymentId deploymentId = new DeploymentId(application.id(), deployment.zone());
try {
NodeList nodes = controller().applications().configserverClient().getNodeList(deploymentId);
- Map<ClusterSpec.Id, ClusterInfo> clusterInfo = getClusterInfo(nodes);
+ Map<ClusterSpec.Id, ClusterInfo> clusterInfo = getClusterInfo(nodes, deployment.zone());
Application app = application.with(deployment.withClusterInfo(clusterInfo));
controller.applications().store(app, lock);
} catch (IOException ioe) {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
index 859e322b227..70a878ef93f 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java
@@ -134,7 +134,7 @@ public class ApplicationSerializer {
private void toSlime(ClusterInfo info, Cursor object) {
object.setString(clusterInfoFlavorField, info.getFlavor());
- object.setLong(clusterInfoCostField, info.getCost());
+ object.setLong(clusterInfoCostField, info.getFlavorCost());
object.setString(clusterInfoTypeField, info.getClusterType().name());
Cursor array = object.setArray(clusterInfoHostnamesField);
for (String host : info.getHostnames()) {
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index 42e89e7893f..e4e62379f01 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -1096,8 +1096,12 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
object.setString("resource", getResourceName(clusterCost.getResultUtilization()));
object.setDouble("utilization", clusterCost.getResultUtilization().getMaxUtilization());
object.setLong("tco", (int)clusterCost.getTco());
- object.setString("flavor", clusterCost.getClusterInfo().getFlavor());
object.setLong("waste", (int)clusterCost.getWaste());
+ object.setString("flavor", clusterCost.getClusterInfo().getFlavor());
+ object.setDouble("flavorCost", clusterCost.getClusterInfo().getFlavorCost());
+ object.setDouble("flavorCpu", clusterCost.getClusterInfo().getFlavorCPU());
+ object.setDouble("flavorMem", clusterCost.getClusterInfo().getFlavorMem());
+ object.setDouble("flavorDisk", clusterCost.getClusterInfo().getFlavorDisk());
object.setString("type", clusterCost.getClusterInfo().getClusterType().name());
Cursor utilObject = object.setObject("util");
utilObject.setDouble("cpu", clusterCost.getResultUtilization().getCpu());
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainerTest.java
index 7ae89082660..13919cefd3b 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/ClusterInfoMaintainerTest.java
@@ -31,7 +31,7 @@ public class ClusterInfoMaintainerTest {
deployment = tester.controller().applications().get(app).get().deployments().values().stream().findAny().get();
Assert.assertEquals(2, deployment.clusterInfo().size());
- Assert.assertEquals(10, deployment.clusterInfo().get(ClusterSpec.Id.from("clusterA")).getCost());
+ Assert.assertEquals(10, deployment.clusterInfo().get(ClusterSpec.Id.from("clusterA")).getFlavorCost());
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
index 3e73bf4445b..22d67b7af7d 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java
@@ -118,7 +118,7 @@ public class ApplicationSerializerTest {
// Test cluster info
assertEquals(3, serialized.deployments().get(zone2).clusterInfo().size());
- assertEquals(10, serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getCost());
+ assertEquals(10, serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getFlavorCost());
assertEquals(ClusterSpec.Type.content, serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getClusterType());
assertEquals("flavor2", serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getFlavor());
assertEquals(4, serialized.deployments().get(zone2).clusterInfo().get(ClusterSpec.Id.from("id2")).getHostnames().size());