Sunday, October 13, 2013

Google Guava: missing cache entries

Recently I had to create new caching layer for our web applications. Nothing fancy, just usual multi-level read-through cache. I used Cache from Google Guava library for one of the caching levels, and faced interesting issue. Some tests intermittently failed b/c of the cache data misses, even despite that data was loaded into the cache during test data initialization.

Playing with different cache configurations I found out that data misses happens in a case of full cache population.

Below are the test that demonstrates the issue. It creates Cache, populates it with the random data, then reads the data from the cache and and counts number of misses (google guava v. 14).

public class GuavaTest {

    public static void main(String[] args){

        for(int i = 1000; i <= 50000; i += 1000){
            System.out.println(MessageFormat.format("count = {0} missCount = {1}", i, String.valueOf(test(i))));
        }

    }

    public static int test(final int cacheSize){

        String[] urls = new String[cacheSize];
        com.google.common.cache.Cache<Object, Object> cache = CacheBuilder.newBuilder()
                .maximumSize(cacheSize)
                .build();

        for(int i = 0; i < cacheSize; i++){
            urls[i] = UUID.randomUUID().toString();
            cache.put(urls[i], new Object());
        }

        int missCount = 0;

        for(int i = 0; i < cacheSize; i++){
            Object o = cache.getIfPresent(urls[i]);
            if(o == null){
                ++missCount;
            }
        }

        return missCount;
    }
}

Below are results I've got (they're slightly different every time, but trend and range are approx. the same):


I was really surprised with results. Maybe that's the price for some kind of optimization or something. I'm still using guava cache, it is great tool, but always keep in mind that I have to reserve a bit more slots than required number to avoid data loss.


No comments:

Post a Comment