diff options
author | Jon Bratseth <bratseth@verizonmedia.com> | 2019-05-18 15:44:24 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@verizonmedia.com> | 2019-05-18 15:44:24 +0200 |
commit | fddfaf0d3a98b8ea389e032c8e6fc66a0404f542 (patch) | |
tree | 2455bfb8788d41e37d064ea52b501ab028bc03fb /config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java | |
parent | fac14833ab735244d67abd8114a8ca46befe292f (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.java | 81 |
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); } } |