Yes - avoiding an Ignite out of memory condition is exactly what I'm trying
to do. The question is - how can I do this if memory metrics aren't
reliable?

Does anyone have experience of successfully monitoring contracting Ignite
memory consumption? Or does anyone have any more general thoughts on how to
avoid IOOM other than using native persistence?

To be clear, the problem with the metrics is not caused by the IOOM
condition. See the amended example below:

package mytest;

import org.apache.ignite.DataRegionMetrics;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.DataRegionConfiguration;
import org.apache.ignite.configuration.DataStorageConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.failure.NoOpFailureHandler;
import org.junit.Test;

public class MemoryTest2 {

    private static final String CACHE_NAME = "cache";
    private static final String DEFAULT_MEMORY_REGION = "Default_Region";
    private static final long MEM_SIZE = 100L * 1024 * 1024;


    @Test
    public void testOOM() throws InterruptedException {
        try (Ignite ignite = startIgnite("IgniteMemoryMonitorTest1")) {
            fillDataRegion(ignite);
            CacheConfiguration<Object, Object> cfg = new
CacheConfiguration<>(CACHE_NAME);
            cfg.setStatisticsEnabled(true);
            IgniteCache<Object, Object> cache =
ignite.getOrCreateCache(cfg);

            // Clear all entries from the cache to free up memory 
            memUsed(ignite);
            cache.clear();
            cache.removeAll();
            cache.put("Key", "Value");
            memUsed(ignite);
            cache.destroy();
            Thread.sleep(5000);

            // Should now report close to 0% but reports 59% still
            memUsed(ignite);
        }
    }
    
    private Ignite startIgnite(String instanceName) {
        IgniteConfiguration cfg = new IgniteConfiguration();
        cfg.setIgniteInstanceName(instanceName);
        cfg.setDataStorageConfiguration(createDataStorageConfiguration());
        cfg.setFailureHandler(new NoOpFailureHandler());
        return Ignition.start(cfg);
    }

    private DataStorageConfiguration createDataStorageConfiguration() {
        return new DataStorageConfiguration()
                .setDefaultDataRegionConfiguration(
                        new DataRegionConfiguration()
                                .setName(DEFAULT_MEMORY_REGION)
                                .setInitialSize(MEM_SIZE)
                                .setMaxSize(MEM_SIZE)
                                .setMetricsEnabled(true));
    }

    private void fillDataRegion(Ignite ignite) {
        byte[] megabyte = new byte[1024 * 1024];
            IgniteCache<Object, Object> cache =
                    ignite.getOrCreateCache(CACHE_NAME);
            for (int i = 0; i < 50; i++) {
                cache.put(i, megabyte);
                memUsed(ignite);
            }
    }

    private void memUsed(Ignite ignite) {
        DataRegionConfiguration defaultDataRegionCfg =
ignite.configuration()
                .getDataStorageConfiguration()
                .getDefaultDataRegionConfiguration();
        String regionName = defaultDataRegionCfg.getName();
        DataRegionMetrics metrics = ignite.dataRegionMetrics(regionName);
        float usedMem = metrics.getPagesFillFactor() *
metrics.getTotalAllocatedPages() * metrics.getPageSize();
        float pctUsed = 100 * usedMem / defaultDataRegionCfg.getMaxSize();
        System.out.println("Memory used: " + pctUsed + "%");
    }
} 



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/

Reply via email to