Search in sources :

Example 1 with EntityCache

use of org.opensearch.ad.caching.EntityCache in project anomaly-detection by opensearch-project.

the class ADStatsTests method setup.

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
    // sampleSize * numberOfTrees has to be larger than 1. Otherwise, RCF reports errors.
    rcf = RandomCutForest.builder().dimensions(1).sampleSize(2).numberOfTrees(1).build();
    thresholdingModel = new HybridThresholdingModel(1e-8, 1e-5, 200, 10_000, 2, 5_000_000);
    List<ModelState<?>> modelsInformation = new ArrayList<>(Arrays.asList(new ModelState<>(rcf, "rcf-model-1", "detector-1", ModelManager.ModelType.RCF.getName(), clock, 0f), new ModelState<>(thresholdingModel, "thr-model-1", "detector-1", ModelManager.ModelType.RCF.getName(), clock, 0f), new ModelState<>(rcf, "rcf-model-2", "detector-2", ModelManager.ModelType.THRESHOLD.getName(), clock, 0f), new ModelState<>(thresholdingModel, "thr-model-2", "detector-2", ModelManager.ModelType.THRESHOLD.getName(), clock, 0f)));
    when(modelManager.getAllModels()).thenReturn(modelsInformation);
    ModelState<EntityModel> entityModel1 = MLUtil.randomModelState(new RandomModelStateConfig.Builder().fullModel(true).build());
    ModelState<EntityModel> entityModel2 = MLUtil.randomModelState(new RandomModelStateConfig.Builder().fullModel(true).build());
    List<ModelState<?>> entityModelsInformation = new ArrayList<>(Arrays.asList(entityModel1, entityModel2));
    EntityCache cache = mock(EntityCache.class);
    when(cacheProvider.get()).thenReturn(cache);
    when(cache.getAllModels()).thenReturn(entityModelsInformation);
    IndexUtils indexUtils = mock(IndexUtils.class);
    when(indexUtils.getIndexHealthStatus(anyString())).thenReturn("yellow");
    when(indexUtils.getNumberOfDocumentsInIndex(anyString())).thenReturn(100L);
    clusterStatName1 = "clusterStat1";
    clusterStatName2 = "clusterStat2";
    nodeStatName1 = "nodeStat1";
    nodeStatName2 = "nodeStat2";
    Settings settings = Settings.builder().put(MAX_MODEL_SIZE_PER_NODE.getKey(), 10).build();
    ClusterService clusterService = mock(ClusterService.class);
    ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, Collections.unmodifiableSet(new HashSet<>(Arrays.asList(MAX_MODEL_SIZE_PER_NODE))));
    when(clusterService.getClusterSettings()).thenReturn(clusterSettings);
    statsMap = new HashMap<String, ADStat<?>>() {

        {
            put(nodeStatName1, new ADStat<>(false, new CounterSupplier()));
            put(nodeStatName2, new ADStat<>(false, new ModelsOnNodeSupplier(modelManager, cacheProvider, settings, clusterService)));
            put(clusterStatName1, new ADStat<>(true, new IndexStatusSupplier(indexUtils, "index1")));
            put(clusterStatName2, new ADStat<>(true, new IndexStatusSupplier(indexUtils, "index2")));
        }
    };
    adStats = new ADStats(statsMap);
}
Also used : ModelsOnNodeSupplier(org.opensearch.ad.stats.suppliers.ModelsOnNodeSupplier) ClusterSettings(org.opensearch.common.settings.ClusterSettings) EntityCache(org.opensearch.ad.caching.EntityCache) ArrayList(java.util.ArrayList) EntityModel(org.opensearch.ad.ml.EntityModel) HybridThresholdingModel(org.opensearch.ad.ml.HybridThresholdingModel) ModelState(org.opensearch.ad.ml.ModelState) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) RandomModelStateConfig(test.org.opensearch.ad.util.RandomModelStateConfig) CounterSupplier(org.opensearch.ad.stats.suppliers.CounterSupplier) IndexUtils(org.opensearch.ad.util.IndexUtils) ClusterService(org.opensearch.cluster.service.ClusterService) IndexStatusSupplier(org.opensearch.ad.stats.suppliers.IndexStatusSupplier) ClusterSettings(org.opensearch.common.settings.ClusterSettings) Settings(org.opensearch.common.settings.Settings) HashSet(java.util.HashSet) Before(org.junit.Before)

Example 2 with EntityCache

use of org.opensearch.ad.caching.EntityCache in project anomaly-detection by opensearch-project.

the class ADStatsNodesTransportActionTests method setUp.

@Override
@Before
public void setUp() throws Exception {
    super.setUp();
    Client client = client();
    Clock clock = mock(Clock.class);
    Throttler throttler = new Throttler(clock);
    ThreadPool threadPool = mock(ThreadPool.class);
    IndexNameExpressionResolver indexNameResolver = mock(IndexNameExpressionResolver.class);
    IndexUtils indexUtils = new IndexUtils(client, new ClientUtil(Settings.EMPTY, client, throttler, threadPool), clusterService(), indexNameResolver);
    ModelManager modelManager = mock(ModelManager.class);
    CacheProvider cacheProvider = mock(CacheProvider.class);
    EntityCache cache = mock(EntityCache.class);
    when(cacheProvider.get()).thenReturn(cache);
    clusterStatName1 = "clusterStat1";
    clusterStatName2 = "clusterStat2";
    nodeStatName1 = "nodeStat1";
    nodeStatName2 = "nodeStat2";
    Settings settings = Settings.builder().put(MAX_MODEL_SIZE_PER_NODE.getKey(), 10).build();
    ClusterService clusterService = mock(ClusterService.class);
    ClusterSettings clusterSettings = new ClusterSettings(Settings.EMPTY, Collections.unmodifiableSet(new HashSet<>(Arrays.asList(MAX_MODEL_SIZE_PER_NODE))));
    when(clusterService.getClusterSettings()).thenReturn(clusterSettings);
    statsMap = new HashMap<String, ADStat<?>>() {

        {
            put(nodeStatName1, new ADStat<>(false, new CounterSupplier()));
            put(nodeStatName2, new ADStat<>(false, new ModelsOnNodeSupplier(modelManager, cacheProvider, settings, clusterService)));
            put(clusterStatName1, new ADStat<>(true, new IndexStatusSupplier(indexUtils, "index1")));
            put(clusterStatName2, new ADStat<>(true, new IndexStatusSupplier(indexUtils, "index2")));
            put(InternalStatNames.JVM_HEAP_USAGE.getName(), new ADStat<>(true, new SettableSupplier()));
        }
    };
    adStats = new ADStats(statsMap);
    JvmService jvmService = mock(JvmService.class);
    JvmStats jvmStats = mock(JvmStats.class);
    JvmStats.Mem mem = mock(JvmStats.Mem.class);
    when(jvmService.stats()).thenReturn(jvmStats);
    when(jvmStats.getMem()).thenReturn(mem);
    when(mem.getHeapUsedPercent()).thenReturn(randomShort());
    adTaskManager = mock(ADTaskManager.class);
    action = new ADStatsNodesTransportAction(client().threadPool(), clusterService(), mock(TransportService.class), mock(ActionFilters.class), adStats, jvmService, adTaskManager);
}
Also used : ModelsOnNodeSupplier(org.opensearch.ad.stats.suppliers.ModelsOnNodeSupplier) ClusterSettings(org.opensearch.common.settings.ClusterSettings) EntityCache(org.opensearch.ad.caching.EntityCache) ClientUtil(org.opensearch.ad.util.ClientUtil) ADStat(org.opensearch.ad.stats.ADStat) ThreadPool(org.opensearch.threadpool.ThreadPool) Clock(java.time.Clock) CounterSupplier(org.opensearch.ad.stats.suppliers.CounterSupplier) IndexUtils(org.opensearch.ad.util.IndexUtils) JvmService(org.opensearch.monitor.jvm.JvmService) Client(org.opensearch.client.Client) ClusterSettings(org.opensearch.common.settings.ClusterSettings) Settings(org.opensearch.common.settings.Settings) Throttler(org.opensearch.ad.util.Throttler) HashSet(java.util.HashSet) JvmStats(org.opensearch.monitor.jvm.JvmStats) ModelManager(org.opensearch.ad.ml.ModelManager) CacheProvider(org.opensearch.ad.caching.CacheProvider) SettableSupplier(org.opensearch.ad.stats.suppliers.SettableSupplier) ClusterService(org.opensearch.cluster.service.ClusterService) IndexStatusSupplier(org.opensearch.ad.stats.suppliers.IndexStatusSupplier) ADTaskManager(org.opensearch.ad.task.ADTaskManager) ADStats(org.opensearch.ad.stats.ADStats) IndexNameExpressionResolver(org.opensearch.cluster.metadata.IndexNameExpressionResolver) Before(org.junit.Before)

Example 3 with EntityCache

use of org.opensearch.ad.caching.EntityCache in project anomaly-detection by opensearch-project.

the class ModelsOnNodeSupplierTests method setup.

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
    clock = Clock.systemUTC();
    rcf = RandomCutForest.builder().dimensions(1).sampleSize(2).numberOfTrees(1).build();
    thresholdingModel = new HybridThresholdingModel(1e-8, 1e-5, 200, 10_000, 2, 5_000_000);
    expectedResults = new ArrayList<>(Arrays.asList(new ModelState<>(rcf, "rcf-model-1", "detector-1", ModelManager.ModelType.RCF.getName(), clock, 0f), new ModelState<>(thresholdingModel, "thr-model-1", "detector-1", ModelManager.ModelType.RCF.getName(), clock, 0f), new ModelState<>(rcf, "rcf-model-2", "detector-2", ModelManager.ModelType.THRESHOLD.getName(), clock, 0f), new ModelState<>(thresholdingModel, "thr-model-2", "detector-2", ModelManager.ModelType.THRESHOLD.getName(), clock, 0f)));
    when(modelManager.getAllModels()).thenReturn(expectedResults);
    ModelState<EntityModel> entityModel1 = MLUtil.randomModelState(new RandomModelStateConfig.Builder().fullModel(true).build());
    ModelState<EntityModel> entityModel2 = MLUtil.randomModelState(new RandomModelStateConfig.Builder().fullModel(true).build());
    entityModelsInformation = new ArrayList<>(Arrays.asList(entityModel1, entityModel2));
    EntityCache cache = mock(EntityCache.class);
    when(cacheProvider.get()).thenReturn(cache);
    when(cache.getAllModels()).thenReturn(entityModelsInformation);
}
Also used : RandomModelStateConfig(test.org.opensearch.ad.util.RandomModelStateConfig) EntityCache(org.opensearch.ad.caching.EntityCache) EntityModel(org.opensearch.ad.ml.EntityModel) HybridThresholdingModel(org.opensearch.ad.ml.HybridThresholdingModel) Before(org.junit.Before)

Example 4 with EntityCache

use of org.opensearch.ad.caching.EntityCache in project anomaly-detection by opensearch-project.

the class EntityProfileTransportAction method doExecute.

@Override
protected void doExecute(Task task, EntityProfileRequest request, ActionListener<EntityProfileResponse> listener) {
    String adID = request.getAdID();
    Entity entityValue = request.getEntityValue();
    Optional<String> modelIdOptional = entityValue.getModelId(adID);
    if (false == modelIdOptional.isPresent()) {
        listener.onFailure(new AnomalyDetectionException(adID, NO_MODEL_ID_FOUND_MSG));
        return;
    }
    // we use entity's toString (e.g., app_0) to find its node
    // This should be consistent with how we land a model node in AnomalyResultTransportAction
    Optional<DiscoveryNode> node = hashRing.getOwningNodeWithSameLocalAdVersionForRealtimeAD(entityValue.toString());
    if (false == node.isPresent()) {
        listener.onFailure(new AnomalyDetectionException(adID, NO_NODE_FOUND_MSG));
        return;
    }
    String nodeId = node.get().getId();
    String modelId = modelIdOptional.get();
    DiscoveryNode localNode = clusterService.localNode();
    if (localNode.getId().equals(nodeId)) {
        EntityCache cache = cacheProvider.get();
        Set<EntityProfileName> profilesToCollect = request.getProfilesToCollect();
        EntityProfileResponse.Builder builder = new EntityProfileResponse.Builder();
        if (profilesToCollect.contains(EntityProfileName.ENTITY_INFO)) {
            builder.setActive(cache.isActive(adID, modelId));
            builder.setLastActiveMs(cache.getLastActiveMs(adID, modelId));
        }
        if (profilesToCollect.contains(EntityProfileName.INIT_PROGRESS) || profilesToCollect.contains(EntityProfileName.STATE)) {
            builder.setTotalUpdates(cache.getTotalUpdates(adID, modelId));
        }
        if (profilesToCollect.contains(EntityProfileName.MODELS)) {
            Optional<ModelProfile> modleProfile = cache.getModelProfile(adID, modelId);
            if (modleProfile.isPresent()) {
                builder.setModelProfile(new ModelProfileOnNode(nodeId, modleProfile.get()));
            }
        }
        listener.onResponse(builder.build());
    } else if (request.remoteAddress() == null) {
        // redirect if request comes from local host.
        // If a request comes from remote machine, it is already redirected.
        // One redirection should be enough.
        // We don't want a potential infinite loop due to any bug and thus give up.
        LOG.info("Sending entity profile request to {} for detector {}, entity {}", nodeId, adID, entityValue);
        try {
            transportService.sendRequest(node.get(), EntityProfileAction.NAME, request, option, new TransportResponseHandler<EntityProfileResponse>() {

                @Override
                public EntityProfileResponse read(StreamInput in) throws IOException {
                    return new EntityProfileResponse(in);
                }

                @Override
                public void handleResponse(EntityProfileResponse response) {
                    listener.onResponse(response);
                }

                @Override
                public void handleException(TransportException exp) {
                    listener.onFailure(exp);
                }

                @Override
                public String executor() {
                    return ThreadPool.Names.SAME;
                }
            });
        } catch (Exception e) {
            LOG.error(String.format(Locale.ROOT, "Fail to get entity profile for detector {}, entity {}", adID, entityValue), e);
            listener.onFailure(new AnomalyDetectionException(adID, FAIL_TO_GET_ENTITY_PROFILE_MSG, e));
        }
    } else {
        // Prior to Opensearch 1.1, we map a node using model id in the profile API.
        // This is not consistent how we map node in AnomalyResultTransportAction, where
        // we use entity values. We fixed that bug in Opensearch 1.1. But this can cause
        // issue when a request involving an old node according to model id.
        // The new node finds the entity value does not map to itself, so it redirects to another node.
        // The redirection can cause an infinite loop. This branch breaks the loop and gives up.
        LOG.error("Fail to get entity profile for detector {}, entity {}. Maybe because old and new node" + " are using different keys for the hash ring.", adID, entityValue);
        listener.onFailure(new AnomalyDetectionException(adID, FAIL_TO_GET_ENTITY_PROFILE_MSG));
    }
}
Also used : AnomalyDetectionException(org.opensearch.ad.common.exception.AnomalyDetectionException) Entity(org.opensearch.ad.model.Entity) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) EntityCache(org.opensearch.ad.caching.EntityCache) ModelProfileOnNode(org.opensearch.ad.model.ModelProfileOnNode) TransportResponseHandler(org.opensearch.transport.TransportResponseHandler) TransportException(org.opensearch.transport.TransportException) ModelProfile(org.opensearch.ad.model.ModelProfile) AnomalyDetectionException(org.opensearch.ad.common.exception.AnomalyDetectionException) IOException(java.io.IOException) TransportException(org.opensearch.transport.TransportException) StreamInput(org.opensearch.common.io.stream.StreamInput) EntityProfileName(org.opensearch.ad.model.EntityProfileName)

Example 5 with EntityCache

use of org.opensearch.ad.caching.EntityCache in project anomaly-detection by opensearch-project.

the class CheckpointReadWorkerTests method setUp.

@Override
public void setUp() throws Exception {
    super.setUp();
    clusterService = mock(ClusterService.class);
    clusterSettings = new ClusterSettings(Settings.EMPTY, Collections.unmodifiableSet(new HashSet<>(Arrays.asList(AnomalyDetectorSettings.CHECKPOINT_READ_QUEUE_MAX_HEAP_PERCENT, AnomalyDetectorSettings.CHECKPOINT_READ_QUEUE_CONCURRENCY, AnomalyDetectorSettings.CHECKPOINT_READ_QUEUE_BATCH_SIZE))));
    when(clusterService.getClusterSettings()).thenReturn(clusterSettings);
    state = MLUtil.randomModelState(new RandomModelStateConfig.Builder().fullModel(true).build());
    checkpoint = mock(CheckpointDao.class);
    Map.Entry<EntityModel, Instant> entry = new SimpleImmutableEntry<EntityModel, Instant>(state.getModel(), Instant.now());
    when(checkpoint.processGetResponse(any(), anyString())).thenReturn(Optional.of(entry));
    checkpointWriteQueue = mock(CheckpointWriteWorker.class);
    modelManager = mock(ModelManager.class);
    when(modelManager.processEntityCheckpoint(any(), any(), anyString(), anyString(), anyInt())).thenReturn(state);
    when(modelManager.score(any(), anyString(), any())).thenReturn(new ThresholdingResult(0, 1, 0.7));
    coldstartQueue = mock(EntityColdStartWorker.class);
    resultWriteQueue = mock(ResultWriteWorker.class);
    anomalyDetectionIndices = mock(AnomalyDetectionIndices.class);
    cacheProvider = mock(CacheProvider.class);
    entityCache = mock(EntityCache.class);
    when(cacheProvider.get()).thenReturn(entityCache);
    when(entityCache.hostIfPossible(any(), any())).thenReturn(true);
    // Integer.MAX_VALUE makes a huge heap
    worker = new CheckpointReadWorker(Integer.MAX_VALUE, AnomalyDetectorSettings.ENTITY_FEATURE_REQUEST_SIZE_IN_BYTES, AnomalyDetectorSettings.CHECKPOINT_READ_QUEUE_MAX_HEAP_PERCENT, clusterService, new Random(42), mock(ADCircuitBreakerService.class), threadPool, Settings.EMPTY, AnomalyDetectorSettings.MAX_QUEUED_TASKS_RATIO, clock, AnomalyDetectorSettings.MEDIUM_SEGMENT_PRUNE_RATIO, AnomalyDetectorSettings.LOW_SEGMENT_PRUNE_RATIO, AnomalyDetectorSettings.MAINTENANCE_FREQ_CONSTANT, AnomalyDetectorSettings.QUEUE_MAINTENANCE, modelManager, checkpoint, coldstartQueue, resultWriteQueue, nodeStateManager, anomalyDetectionIndices, cacheProvider, AnomalyDetectorSettings.HOURLY_MAINTENANCE, checkpointWriteQueue);
    request = new EntityFeatureRequest(Integer.MAX_VALUE, detectorId, RequestPriority.MEDIUM, entity, new double[] { 0 }, 0);
    request2 = new EntityFeatureRequest(Integer.MAX_VALUE, detectorId, RequestPriority.MEDIUM, entity2, new double[] { 0 }, 0);
    request3 = new EntityFeatureRequest(Integer.MAX_VALUE, detectorId, RequestPriority.MEDIUM, entity3, new double[] { 0 }, 0);
}
Also used : ClusterSettings(org.opensearch.common.settings.ClusterSettings) EntityCache(org.opensearch.ad.caching.EntityCache) Instant(java.time.Instant) EntityModel(org.opensearch.ad.ml.EntityModel) ModelManager(org.opensearch.ad.ml.ModelManager) CacheProvider(org.opensearch.ad.caching.CacheProvider) ThresholdingResult(org.opensearch.ad.ml.ThresholdingResult) ClusterService(org.opensearch.cluster.service.ClusterService) CheckpointDao(org.opensearch.ad.ml.CheckpointDao) Random(java.util.Random) SimpleImmutableEntry(java.util.AbstractMap.SimpleImmutableEntry) AnomalyDetectionIndices(org.opensearch.ad.indices.AnomalyDetectionIndices) Map(java.util.Map)

Aggregations

EntityCache (org.opensearch.ad.caching.EntityCache)13 CacheProvider (org.opensearch.ad.caching.CacheProvider)10 Before (org.junit.Before)8 ModelManager (org.opensearch.ad.ml.ModelManager)8 ActionFilters (org.opensearch.action.support.ActionFilters)6 ClusterService (org.opensearch.cluster.service.ClusterService)6 ArrayList (java.util.ArrayList)5 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)5 FeatureManager (org.opensearch.ad.feature.FeatureManager)5 Entity (org.opensearch.ad.model.Entity)5 DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)5 ClusterSettings (org.opensearch.common.settings.ClusterSettings)5 Settings (org.opensearch.common.settings.Settings)5 TransportService (org.opensearch.transport.TransportService)5 HashSet (java.util.HashSet)4 NodeStateManager (org.opensearch.ad.NodeStateManager)4 AnomalyDetectionIndices (org.opensearch.ad.indices.AnomalyDetectionIndices)4 EntityModel (org.opensearch.ad.ml.EntityModel)4 CounterSupplier (org.opensearch.ad.stats.suppliers.CounterSupplier)4 ThreadPool (org.opensearch.threadpool.ThreadPool)4