summaryrefslogtreecommitdiffstats
path: root/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@verizonmedia.com>2019-05-18 15:44:24 +0200
committerJon Bratseth <bratseth@verizonmedia.com>2019-05-18 15:44:24 +0200
commitfddfaf0d3a98b8ea389e032c8e6fc66a0404f542 (patch)
tree2455bfb8788d41e37d064ea52b501ab028bc03fb /config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java
parentfac14833ab735244d67abd8114a8ca46befe292f (diff)
Take disk speed into account
Diffstat (limited to 'config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java')
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java81
1 files changed, 76 insertions, 5 deletions
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java
index 005bfac6b5c..b5d16c35dac 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java
@@ -1,6 +1,7 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.provision;
+import java.util.Objects;
import java.util.Optional;
/**
@@ -10,27 +11,42 @@ import java.util.Optional;
*/
public class NodeResources {
+ public enum DiskSpeed {
+ fast, // SSD disk or similar speed is needed
+ slow, // This is tuned to work with the speed of spinning disks
+ any // The performance of the cluster using this does not depend on disk speed
+ }
+
private final double vcpu;
private final double memoryGb;
private final double diskGb;
+ private final DiskSpeed diskSpeed;
private final boolean allocateByLegacyName;
/** The legacy (flavor) name of this, or null if none */
private final String legacyName;
+ /** Create node resources requiring fast disk */
public NodeResources(double vcpu, double memoryGb, double diskGb) {
+ this(vcpu, memoryGb, diskGb, DiskSpeed.fast);
+ }
+
+ public NodeResources(double vcpu, double memoryGb, double diskGb, DiskSpeed diskSpeed) {
this.vcpu = vcpu;
this.memoryGb = memoryGb;
this.diskGb = diskGb;
+ this.diskSpeed = diskSpeed;
this.allocateByLegacyName = false;
this.legacyName = null;
}
- private NodeResources(double vcpu, double memoryGb, double diskGb, boolean allocateByLegacyName, String legacyName) {
+ private NodeResources(double vcpu, double memoryGb, double diskGb, DiskSpeed diskSpeed,
+ boolean allocateByLegacyName, String legacyName) {
this.vcpu = vcpu;
this.memoryGb = memoryGb;
this.diskGb = diskGb;
+ this.diskSpeed = diskSpeed;
this.allocateByLegacyName = allocateByLegacyName;
this.legacyName = legacyName;
}
@@ -38,6 +54,25 @@ public class NodeResources {
public double vcpu() { return vcpu; }
public double memoryGb() { return memoryGb; }
public double diskGb() { return diskGb; }
+ public DiskSpeed diskSpeed() { return diskSpeed; }
+
+ public NodeResources subtract(NodeResources other) {
+ if ( ! this.isInterchangeableWith(other))
+ throw new IllegalArgumentException(this + " and " + other + " are not interchangeable");
+ return new NodeResources(vcpu - other.vcpu,
+ memoryGb - other.memoryGb,
+ diskGb - other.diskGb,
+ combine(this.diskSpeed, other.diskSpeed));
+ }
+
+ public NodeResources add(NodeResources other) {
+ if ( ! this.isInterchangeableWith(other))
+ throw new IllegalArgumentException(this + " and " + other + " are not interchangeable");
+ return new NodeResources(vcpu + other.vcpu,
+ memoryGb + other.memoryGb,
+ diskGb + other.diskGb,
+ combine(this.diskSpeed, other.diskSpeed));
+ }
/**
* If this is true, a non-docker legacy name was used to specify this and we'll respect that by mapping directly.
@@ -50,6 +85,23 @@ public class NodeResources {
return Optional.ofNullable(legacyName);
}
+ private boolean isInterchangeableWith(NodeResources other) {
+ if (this.allocateByLegacyName != other.allocateByLegacyName) return false;
+ if (this.allocateByLegacyName) return legacyName.equals(other.legacyName);
+
+ if (this.diskSpeed != DiskSpeed.any && other.diskSpeed != DiskSpeed.any && this.diskSpeed != other.diskSpeed)
+ return false;
+
+ return true;
+ }
+
+ private DiskSpeed combine(DiskSpeed a, DiskSpeed b) {
+ if (a == DiskSpeed.any) return b;
+ if (b == DiskSpeed.any) return a;
+ if (a == b) return a;
+ throw new IllegalArgumentException(a + " cannot be combined with " + b);
+ }
+
@Override
public boolean equals(Object o) {
if (o == this) return true;
@@ -62,6 +114,7 @@ public class NodeResources {
if (this.vcpu != other.vcpu) return false;
if (this.memoryGb != other.memoryGb) return false;
if (this.diskGb != other.diskGb) return false;
+ if (this.diskSpeed != other.diskSpeed) return false;
return true;
}
}
@@ -71,7 +124,7 @@ public class NodeResources {
if (allocateByLegacyName)
return legacyName.hashCode();
else
- return (int)(2503 * vcpu + 22123 * memoryGb + 26987 * diskGb);
+ return (int)(2503 * vcpu + 22123 * memoryGb + 26987 * diskGb + diskSpeed.hashCode());
}
@Override
@@ -79,7 +132,25 @@ public class NodeResources {
if (allocateByLegacyName)
return "flavor '" + legacyName + "'";
else
- return "[vcpu: " + vcpu + ", memory: " + memoryGb + " Gb, disk " + diskGb + " Gb]";
+ return "[vcpu: " + vcpu + ", memory: " + memoryGb + " Gb, disk " + diskGb + " Gb" +
+ (diskSpeed != DiskSpeed.fast ? ", disk speed: " + diskSpeed : "") + "]";
+ }
+
+ /** Returns true if all the resources of this are the same or larger than the given resources */
+ public boolean satisfies(NodeResources other) {
+ if (this.allocateByLegacyName || other.allocateByLegacyName) // resources are not available
+ return Objects.equals(this.legacyName, other.legacyName);
+
+ if (this.vcpu < other.vcpu()) return false;
+ if (this.memoryGb < other.memoryGb) return false;
+ if (this.diskGb < other.diskGb) return false;
+
+ // Why doesn't a fast disk satisfy a slow disk? Because if slow disk is explicitly specified
+ // (i.e not "any"), you should not randomly, sometimes get a faster disk as that means you may
+ // draw conclusions about performance on the basis of better resources than you think you have
+ if (other.diskSpeed != DiskSpeed.any && other.diskSpeed != this.diskSpeed) return false;
+
+ return true;
}
/**
@@ -96,10 +167,10 @@ public class NodeResources {
if (cpu == 0) cpu = 0.5;
if (cpu == 2 && mem == 8 ) cpu = 1.5;
if (cpu == 2 && mem == 12 ) cpu = 2.3;
- return new NodeResources(cpu, mem, dsk, false, flavorString);
+ return new NodeResources(cpu, mem, dsk, DiskSpeed.fast, false, flavorString);
}
else { // Another legacy flavor: Allocate by direct matching
- return new NodeResources(0, 0, 0, true, flavorString);
+ return new NodeResources(0, 0, 0, DiskSpeed.fast, true, flavorString);
}
}