How to avoid lost data in Terracotta BigMemory Go

271 views Asked by At

I'm testing BigMemory Go performances, and I notice lost of data.

This is the unit test:

public class BigMemoryGoPerformanceTest {

    public static void main(String[] args) throws IOException {
        BigMemoryGoPerformanceTest test = new BigMemoryGoPerformanceTest();
        test.testBigMemoryGoPerformance(args[0], Long.valueOf(args[1]), Long.valueOf(args[2]));
    }

    @DataProvider(name = "bigMemoryGoPerformance")
    public Object[][] bigMemoryGoPerformance() {
        return new Object[][] {
                   { "very small", 250000, 1 }
                  ,{ "small", 1000000, 2 }
                  ,{ "large", 10000000, 2 }
                  ,{ "very large", 50000000, 4 }
        };
    }

    @Test(dataProvider="bigMemoryGoPerformance")
    public void testBigMemoryGoPerformance(String testName, long maxRegisters, long externalMemory) throws IOException {

        Configuration managerConfiguration = new Configuration();
        managerConfiguration.updateCheck(true)
            .monitoring(Configuration.Monitoring.AUTODETECT)
            .name("config")
            .cache(new CacheConfiguration()
                .name("testperformance")
                .maxBytesLocalHeap(128, MemoryUnit.MEGABYTES)
                .maxBytesLocalOffHeap(externalMemory, MemoryUnit.GIGABYTES)
                .eternal(true)
            );

        CacheManager manager = CacheManager.create(managerConfiguration);
        Cache cache = manager.getCache("testperformance");

        try {
            System.out.println("First pass: insert " + maxRegisters + " nodes.");
            long mms = System.currentTimeMillis();
            for (long i = 0; i < maxRegisters; i++) {
                ItemForTesting item = new ItemForTesting();
                item.id = i;
                item.lastWay = i;
                item.latitude = new Double(i);
                item.longitude = new Double(i);
                cache.put( new Element(i, item) );
            }
            long timeInMMS = System.currentTimeMillis() - mms;
            System.out.println(testName + " --> Inserted " + maxRegisters + " registers in " + timeInMMS + " mms. Performance: " + ((long)(maxRegisters * 1000d / timeInMMS)) + " regs per seconds writing." );


            System.out.println("Second pass: reading " + maxRegisters + " nodes.");
            mms = System.currentTimeMillis();
            for (long i = 0; i < maxRegisters; i++) {
                Element element = cache.get(i);
                ItemForTesting item = (ItemForTesting)element.getObjectValue(); // <--- Null point exception !!!!!
            }
            timeInMMS = System.currentTimeMillis() - mms;
            System.out.println(testName + " --> Read " + maxRegisters + " registers in " + timeInMMS + " mms. Performance: " + ((long)(maxRegisters * 1000d / timeInMMS)) + " regs per seconds reading." );

            System.out.println("Third pass: updating " + maxRegisters + " nodes.");
            mms = System.currentTimeMillis();
            for (long i = 0; i < maxRegisters; i++) {
                Element element = cache.get(i);
                ItemForTesting item = (ItemForTesting)element.getObjectValue();
                item.latitude = item.latitude +1;
                cache.put( new Element(i, item) );
            }
            timeInMMS = System.currentTimeMillis() - mms;
            System.out.println(testName + " --> Updated " + maxRegisters + " registers in " + timeInMMS + " mms. Performance: " + ((long)(maxRegisters * 1000d / timeInMMS)) + " regs per seconds reading." );

            System.out.println("Fourth pass: deleting " + maxRegisters + " nodes.");
            mms = System.currentTimeMillis();
            for (long i = 0; i < maxRegisters; i++) {
                Element element = cache.get(i);
                ItemForTesting item = (ItemForTesting)element.getObjectValue();
                item.latitude = item.latitude +1;
                cache.remove( new Element(i, item) );
            }
            timeInMMS = System.currentTimeMillis() - mms;
            System.out.println(testName + " --> Removed " + maxRegisters + " registers in " + timeInMMS + " mms. Performance: " + ((long)(maxRegisters * 1000d / timeInMMS)) + " regs per seconds reading." );


        } finally {
            if (manager != null) manager.shutdown();
        }

    }

}

In "very large", using 50.000.000 iterations, when read data in second pass, return null. So data is lost!! Configuration is set to eternal = true. How to avoid lost data?

What is it wrong?

Thanks!

2

There are 2 answers

0
hickin On BEST ANSWER

I suspect you need to pin the elements to avoid their expiration. Try config that looks something like this:

<cache name="myBigMemoryGoStore"
    maxBytesLocalHeap="1M"
    eternal="true"
    maxBytesLocalOffHeap="2G">
    <persistence strategy="none"/>
    <pinning store="inCache" />
    <sizeOfPolicy maxDepth="100000" maxDepthExceededBehavior="continue"/>

http://terracotta.org/documentation/4.0/bigmemorygo/configuration/data-life

0
rattletr On

The data might be getting evicted due to heap/offheap pressure. As suggested above, you can use pinning to ensure that you never loose your data. But pinning should only be used when you are sure about the cache sizes, because pinned caches can potentially grow to unlimited sizes or lead to OOME based on the version that you might be using.

On another note to test the performance of BigMemory Go, I recommend using a multithreaded test to get more throughput rather than just using the large number of iterations.

Cheers, Ridhav