You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ignite.apache.org by "Colin Cassidy (Jira)" <ji...@apache.org> on 2019/09/30 12:16:00 UTC

[jira] [Updated] (IGNITE-12096) Ignite memory metrics incorrect on cache usage contraction

     [ https://issues.apache.org/jira/browse/IGNITE-12096?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Colin Cassidy updated IGNITE-12096:
-----------------------------------
    Description: 
When using the Ignite metrics API to measure available memory, the usage figures appear to be accurate while memory is being consumed - but when memory is freed the metrics do not drop. They appear to report that memory has not been freed up, even though it has.

A reliable estimate of memory consumption is very important for solutions that don't use native persistence - as this is the only controllable way of avoiding a critical OOM condition.

Reproducer below. This affects Ignite 2.7+.

{{}}{{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 + "%"); }}
 {{    } }}
 {{} }}

  was:
When using the Ignite metrics API to measure available memory, the usage figures appear to be accurate while memory is being consumed - but when memory is freed the metrics do not drop. They appear to report that memory has not been freed up, even though it has.

Reproducer below. This affects Ignite 2.7+.

{{}}{{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 + "%"); }}
{{    } }}
{{} }}


> Ignite memory metrics incorrect on cache usage contraction
> ----------------------------------------------------------
>
>                 Key: IGNITE-12096
>                 URL: https://issues.apache.org/jira/browse/IGNITE-12096
>             Project: Ignite
>          Issue Type: Bug
>          Components: cache
>    Affects Versions: 2.7
>            Reporter: Colin Cassidy
>            Priority: Critical
>
> When using the Ignite metrics API to measure available memory, the usage figures appear to be accurate while memory is being consumed - but when memory is freed the metrics do not drop. They appear to report that memory has not been freed up, even though it has.
> A reliable estimate of memory consumption is very important for solutions that don't use native persistence - as this is the only controllable way of avoiding a critical OOM condition.
> Reproducer below. This affects Ignite 2.7+.
> {{}}{{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 + "%"); }}
>  {{    } }}
>  {{} }}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)