Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guava cache 'expireAfterWrite' does not seem to always work

Tags:

caching

guava

private Cache<Long, Response> responseCache = CacheBuilder.newBuilder()
            .maximumSize(10000)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build();

I am expecting that response objects that are not send to client within 10 minutes are expired and removed from cache automatically but I notice that Response objects are not always getting expired even after 10, 15, 20 minutes. They do get expire when cache is being populated in large numbers but when the system turn idle, something like last 500 response objects, it stops removing these objects. Can someone help to understand this behavior? Thank you

like image 425
Mark1234 Avatar asked Sep 24 '14 21:09

Mark1234


People also ask

What is expireAfterWrite?

expireAfterWrite. public CacheBuilder<K,V> expireAfterWrite(long duration, TimeUnit unit) Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after the entry's creation, or the most recent replacement of its value.

How does Guava cache work?

The Guava Cache is an incremental cache, in the sense that when you request an object from the cache, it checks to see if it already has the corresponding value for the supplied key. If it does, it simply returns it (assuming it hasn't expired).

Is Google Guava cache distributed?

Hazelcast is for distributed caching, meaning many services share the same cache, whereas Guava/Caffeine is a local cache per each service (not shared).

What is Guava loading cache?

Advertisements. Guava provides a very powerful memory based caching mechanism by an interface LoadingCache<K,V>. Values are automatically loaded in the cache and it provides many utility methods useful for caching needs.


1 Answers

This is specified in the docs:

If expireAfterWrite or expireAfterAccess is requested entries may be evicted on each cache modification, on occasional cache accesses, or on calls to Cache.cleanUp(). Expired entries may be counted by Cache.size(), but will never be visible to read or write operations.

And there's more detail on the wiki:

Caches built with CacheBuilder do not perform cleanup and evict values "automatically," or instantly after a value expires, or anything of the sort. Instead, it performs small amounts of maintenance during write operations, or during occasional read operations if writes are rare.

The reason for this is as follows: if we wanted to perform Cache maintenance continuously, we would need to create a thread, and its operations would be competing with user operations for shared locks. Additionally, some environments restrict the creation of threads, which would make CacheBuilder unusable in that environment.

Instead, we put the choice in your hands. If your cache is high-throughput, then you don't have to worry about performing cache maintenance to clean up expired entries and the like. If your cache does writes only rarely and you don't want cleanup to block cache reads, you may wish to create your own maintenance thread that calls Cache.cleanUp() at regular intervals.

If you want to schedule regular cache maintenance for a cache which only rarely has writes, just schedule the maintenance using ScheduledExecutorService.

like image 161
Louis Wasserman Avatar answered Oct 05 '22 00:10

Louis Wasserman