Browse Source

[ML] Provide model_size_stats as soon as an anomaly detection job is opened (#124638)

Fixes #121168
Valeriy Khakhutskyy 7 months ago
parent
commit
44fba7213d

+ 6 - 0
docs/changelog/124638.yaml

@@ -0,0 +1,6 @@
+pr: 124638
+summary: Provide model size statistics as soon as an anomaly detection job is opened
+area: Machine Learning
+type: bug
+issues:
+ - 121168

+ 31 - 0
x-pack/plugin/ml/qa/native-multi-node-tests/src/javaRestTest/java/org/elasticsearch/xpack/ml/integration/AutodetectMemoryLimitIT.java

@@ -230,6 +230,37 @@ public class AutodetectMemoryLimitIT extends MlNativeAutodetectIntegTestCase {
         assertThat(modelSizeStats.getMemoryStatus(), equalTo(ModelSizeStats.MemoryStatus.HARD_LIMIT));
     }
 
+    public void testOpenJobShouldHaveModelSizeStats() throws Exception {
+        // When a job is opened, it should have non-zero model stats that indicate the memory limit and the assignment basis
+        Detector.Builder detector = new Detector.Builder("sum", "value");
+        detector.setOverFieldName("user");
+
+        TimeValue bucketSpan = TimeValue.timeValueHours(1);
+        AnalysisConfig.Builder analysisConfig = new AnalysisConfig.Builder(Collections.singletonList(detector.build()));
+        analysisConfig.setBucketSpan(bucketSpan);
+        DataDescription.Builder dataDescription = new DataDescription.Builder();
+        dataDescription.setTimeFormat("epoch");
+        Job.Builder job = new Job.Builder("autodetect-open-job-should-have-model-size-stats");
+        job.setAnalysisConfig(analysisConfig);
+        job.setDataDescription(dataDescription);
+
+        // Set the memory limit to 110MB
+        AnalysisLimits limits = new AnalysisLimits(110L, null);
+        job.setAnalysisLimits(limits);
+
+        putJob(job);
+        openJob(job.getId());
+        GetJobsStatsAction.Response.JobStats jobStats = getJobStats(job.getId()).get(0);
+        ModelSizeStats modelSizeStats = jobStats.getModelSizeStats();
+        closeJob(job.getId());
+
+        assertThat(modelSizeStats.getModelBytes(), equalTo(0L));
+        assertThat(modelSizeStats.getModelBytesMemoryLimit(), equalTo(110L));
+        assertThat(modelSizeStats.getMemoryStatus(), equalTo(ModelSizeStats.MemoryStatus.OK));
+        assertThat(modelSizeStats.getAssignmentMemoryBasis(), equalTo(ModelSizeStats.AssignmentMemoryBasis.MODEL_MEMORY_LIMIT));
+
+    }
+
     private static Map<String, Object> createRecord(long timestamp, String user, String department) {
         Map<String, Object> record = new HashMap<>();
         record.put("time", timestamp);

+ 14 - 0
x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/process/autodetect/AutodetectCommunicator.java

@@ -348,9 +348,23 @@ public class AutodetectCommunicator implements Closeable {
     }
 
     public ModelSizeStats getModelSizeStats() {
+        if (isModelSizeStatsAvailable() == false) {
+            return createDefaultModelStats();
+        }
         return autodetectResultProcessor.modelSizeStats();
     }
 
+    private boolean isModelSizeStatsAvailable() {
+        ModelSizeStats modelSizeStats = autodetectResultProcessor.modelSizeStats();
+        return modelSizeStats.getModelBytesMemoryLimit() != null;
+    }
+
+    private ModelSizeStats createDefaultModelStats() {
+        return new ModelSizeStats.Builder(job.getId()).setModelBytesMemoryLimit(job.getAnalysisLimits().getModelMemoryLimit())
+            .setAssignmentMemoryBasis(ModelSizeStats.AssignmentMemoryBasis.MODEL_MEMORY_LIMIT)
+            .build();
+    }
+
     public TimingStats getTimingStats() {
         return autodetectResultProcessor.timingStats();
     }