[ML] Allow xpack.ml.max_machine_memory_percent higher than 100% (#41193)

Values higher than 100% are now allowed to accommodate use
cases where swapping has been determined to be acceptable.
Anomaly detector jobs only use their full model memory
during background persistence, and this is deliberately
staggered, so with large numbers of jobs few will generally
be persisting state at the same time.  Settings higher than
available memory are only recommended for OEM type
situations where a wrapper tightly controls the types of
jobs that can be created, and each job alone is considerably
smaller than what each node can handle.
This commit is contained in:
David Roberts 2019-04-15 14:30:30 +01:00
parent 23e40c040a
commit 3f00c29adb
2 changed files with 30 additions and 1 deletions

View File

@ -271,8 +271,14 @@ public class MachineLearning extends Plugin implements ActionPlugin, AnalysisPlu
public static final String MACHINE_MEMORY_NODE_ATTR = "ml.machine_memory";
public static final Setting<Integer> CONCURRENT_JOB_ALLOCATIONS =
Setting.intSetting("xpack.ml.node_concurrent_job_allocations", 2, 0, Property.Dynamic, Property.NodeScope);
// Values higher than 100% are allowed to accommodate use cases where swapping has been determined to be acceptable.
// Anomaly detector jobs only use their full model memory during background persistence, and this is deliberately
// staggered, so with large numbers of jobs few will generally be persisting state at the same time.
// Settings higher than available memory are only recommended for OEM type situations where a wrapper tightly
// controls the types of jobs that can be created, and each job alone is considerably smaller than what each node
// can handle.
public static final Setting<Integer> MAX_MACHINE_MEMORY_PERCENT =
Setting.intSetting("xpack.ml.max_machine_memory_percent", 30, 5, 90, Property.Dynamic, Property.NodeScope);
Setting.intSetting("xpack.ml.max_machine_memory_percent", 30, 5, 200, Property.Dynamic, Property.NodeScope);
public static final Setting<Integer> MAX_LAZY_ML_NODES =
Setting.intSetting("xpack.ml.max_lazy_ml_nodes", 0, 0, 3, Property.Dynamic, Property.NodeScope);

View File

@ -31,6 +31,29 @@ public class MachineLearningTests extends ESTestCase {
assertEquals(7, maxOpenWorkers);
}
public void testMaxMachineMemoryPercent_givenDefault() {
int maxMachineMemoryPercent = MachineLearning.MAX_MACHINE_MEMORY_PERCENT.get(Settings.EMPTY);
assertEquals(30, maxMachineMemoryPercent);
}
public void testMaxMachineMemoryPercent_givenValidSetting() {
Settings.Builder settings = Settings.builder();
int expectedMaxMachineMemoryPercent = randomIntBetween(5, 200);
settings.put(MachineLearning.MAX_MACHINE_MEMORY_PERCENT.getKey(), expectedMaxMachineMemoryPercent);
int maxMachineMemoryPercent = MachineLearning.MAX_MACHINE_MEMORY_PERCENT.get(settings.build());
assertEquals(expectedMaxMachineMemoryPercent, maxMachineMemoryPercent);
}
public void testMaxMachineMemoryPercent_givenInvalidSetting() {
Settings.Builder settings = Settings.builder();
int invalidMaxMachineMemoryPercent = randomFrom(4, 201);
settings.put(MachineLearning.MAX_MACHINE_MEMORY_PERCENT.getKey(), invalidMaxMachineMemoryPercent);
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> MachineLearning.MAX_MACHINE_MEMORY_PERCENT.get(settings.build()));
assertThat(e.getMessage(), startsWith("Failed to parse value [" + invalidMaxMachineMemoryPercent
+ "] for setting [xpack.ml.max_machine_memory_percent] must be"));
}
public void testNoAttributes_givenNoClash() {
Settings.Builder builder = Settings.builder();
if (randomBoolean()) {