Infinispan supports eviction of entries, such that you do not run out of memory. Eviction is typically used in conjunction with a cache store, so that entries are not permanently lost when evicted, since eviction only removes entries from memory and not from cache stores or the rest of the cluster.
|Passivation is also a popular option when using eviction, so that only a single copy of an entry is maintained - either in memory or in a cache store, but not both. The main benefit of using passivation over a regular cache store is that updates to entries which exist in memory are cheaper since the update doesn't need to be made to the cache store as well.|
Note that eviction occurs on a local basis, and is not cluster-wide. Each node runs an eviction thread to analyse the contents of its in-memory container and decide what to evict. Eviction does not take into account the amount of free memory in the JVM as threshold to starts evicting entries. You have to set maxEntries attribute of the eviction element to be greater than zero in order for eviction to be turned on. If maxEntries is too large you can run out of memory. maxEntries attribute will probably take some tuning in each use case.
Eviction is configured by adding the <eviction /> element to your <default /> or <namedCache /> configuration sections.
This eviction strategy effectively disables the eviction thread.
New in Infinispan 4.1
This eviction strategy means that a simple, un-ordered data container is used. The eviction thread still runs and maintains the size of the data container within certain limits, but it selects entries for eviction in an indeterminate fashion. The benefit of this eviction strategy is that you get an efficient SimpleDataContainer which does not incur the ordering costs of FIFO or LRU, as most operations are performed in constant-time.
This strategy means that entries are selected for eviction using a first-in-first-out pattern. See the Javadocs on the FIFOSimpleDataContainer for information on the algorithm used and the performance tradeoffs involved.
|FIFO has been deprecated as of 5.0. LRU will be used instead|
This strategy means that entries are selected for eviction using a least-recently-used pattern. See the Javadocs on the LRUSimpleDataContainer for information on the algorithm used and the performance tradeoffs involved.
Eviction makes use of a SheduledExecutorService to kick in periodically and inspect the data container for size, and evict entries as needed. This can be tuned using the <evictionScheduledExecutor /> configuration element.
In Infinispan release 4.1 and later releases we have revamped DataContainer abstraction in order to support a more scalable, low lock contention data container structure. In addition to old eviction approaches you can now select LIRS eviction algorithm. LRU remains the default and should be an excellent fit in many deployment scenarios. However, note that LRU eviction algorithm, although simple and easy to understand, under performs in some special cases of so called weak access locality (one time access entries are not timely replaced, entries to be accessed soonest are unfortunately replaced, and so on).
Starting with 4.1 release all cache entry eviction is done in piggyback fashion. Piggyback eviction thread policy, as it name implies, does eviction by piggybacking on user threads that are hitting the data container. Default eviction done on a dedicated EvictionManager thread has been deprecated and even though default eviction thread policy has been chosen in configuration it will fall back to piggyback style. Dedicated EvictionManager has not been completely removed; it is used to prune expired cache entries from cache.
Also note that Infinispan 4.1 release considers only immortal entries for eviction. By default all entries are immortal, that is, their expiration and lifespan are -1. As soon as cache entries are not immortal they are not subject to eviction policies and container size can potentially grow above limit specified in maxEntries. Starting with Infinispan 4.2 and beyond, 5.0 all container entries regardless of their type are considered as eviction candidates.
Implementing eviction in a scalable, low lock contention approach while at the same time doing meaningful selection of entries for eviction is not an easy feat. Data container needs to be locked until appropriate eviction entries are selected. Having such a lock protected data container in turn causes high lock contention offsetting any eviction precision gained by sophisticated eviction algorithms. In order to get superior throughput while retaining high eviction precision both low lock contention data container and high precision eviction algorithm implementation are needed. Infinispan evicts entries from cache on a segment level (segments similar to ConcurrentHashMap), once segment is full entries are evicted according to eviction algorithm. However, there are two drawbacks with this approach. Entries might get evicted from cache even though maxEntries has not been reached yet and maxEntries is a theoretical limit for cache size but in practical terms it will be slightly less than maxEntries. For more details refer to Infinispan eviction design.
Similar to, but unlike eviction, is expiration. Expiration allows you to attach lifespan and/or maximum idle times to entries. Entries that exceed these times are treated as invalid and are removed. When removed expired entries are not passivated like evicted entries (if passivation is turned on).
|Unlike eviction, expired entries are removed globally - from memory, cache stores, and cluster-wide.|
By default entries created are immortal and do not have a lifespan or maximum idle time. Using the cache API, mortal entries can be created with lfiespans and/or maximum idle times. Further, default lifespans and/or maximum idle times can be configured by adding the <expiration /> element to your <default /> or <namedCache /> configuration sections.