Access Keys:
Skip to content (Access Key - 0)

GemFire Versions

About GemFire Enterprise 6.5

Getting Started

Documentation

Resources

Articles

Developer Notes

Tools & Libraries

Toggle Sidebar

Data Eviction

Introduction


Data Eviction allows entries in a GemFire region to be evicted from memory based on a user defined space limit. Evicted entries are either destroyed or [paged to disk]. The least recently used entry is the one that is evicted.

The rest of this article focuses on eviction in general and in particular on eviction that destroys the evicted entry. For information on paging the evicted entry to disk see [Data Paging].

Why evict data?


If you have more data for a region then you can fit in the Java VM's memory then eviction might be the solution for you.

An alternative is to [partition] your data. However even with partitioned regions you may not be able to fit all your data in memory. So you might need to enable eviction on your partitioned region.

Another alternative is to allow some of your data to expire which is time based instead of space based.

Eviction that destroys entries is only viable if the evicted data can be reloaded from an external source. If you need to preserve all your data but it will not fit in memory consider using [data paging].

How to configure a region with destroy eviction


You configure destroy eviction with the action set to local-destroy. For examples of the overflow-to-disk action see [here].
These examples show how to configure three different types of eviction algorithms:

  1. EntryLRU: is configured to start evicting once the region has 76 entries
  2. MemoryLRU: is configured to start evicting once the region contains 99 megabytes of data
  3. HeapLRU: is configured to start evicting once the VM's heap is 75% full

For an example you can actually compile and run see the Cache Eviction Example.
For a description of the eviction attributes see eviction-attributes.

For more information on XML configuration see:

Interaction with other features

As of GemFire 6.5, when eviction that destroys entries is configured on a [replica] it is automatically configured to use the [preloaded] data policy instead. This is because local write operations are not allowed on replicas since they would violate the replica contract that all the data will be present in each copy of the replica. Preloaded behaves much like a replica and allows destroy eviction.

How eviction works


Overview

When using eviction you need to decide on an algorithm to use and an action to take.
The algorithm defines the size limit that will be checked. It can be either EntryLRU, MemoryLRU, or HeapLRU.
The action defines what to do when evicting an entry. It can be one of the following:

  • destroy the entry. This removes its key and value from the local cache.
  • page the entry out to disk. For more on this see [Data Paging].

In order to determine the least recently used entry some extra data is kept on each entry. See this section for a description of the memory overhead.

What counts as a use?

Eviction will evict the least recently used entry. So what entry operations use an entry? Pretty much all of them. Both reads and writes count as a use. It may be easier to describe what entry operations do not use an entry. The following methods will not use the entry:

Entry LRU

This is the simplest algorithm. You specify the number of entries to keep in the region. If you try to put more in then the oldest entries are evicted.
This algorithm is a good choice if all your entries use the same amount of memory.

Memory LRU

This algorithm lets you specify how much memory should be used by your region. If you try to use more than this then the oldest entries will be evicted until you are back under the memory limit.
You may want to configure an ObjectSizer but see the object sizer section to see if the default will work for your use case.
This algorithm is a good choice if your region contains different sizes of entries.

Heap LRU

This algorithm defers to the resource manager's configuration. What is nice about this is it gives you centralized (at the cache level) control of how much memory can be used by multiple regions. You configure on the resource manager what percentage of the Java VM memory can be used by all the HeapLRU regions in a cache. Whenever that percentage is exceeded two things happen:

  • as HeapLRU regions do operations that use more memory they make sure and evict at least that much from their region. This allows the HeapLRU regions to "tread water" at the desired heap percentage.
  • meanwhile a resource manager thread will be asking each HeapLRU region (even if it is currently not growing) to evict some of its contents until the heap usage is back below the eviction threshold.
    Note that this is the only algorithm that will evict data when memory is being consumed by a non-LRU resource. For example if some plug-in in the Java VM allocates a bunch of large objects then this could cause HeapLRU regions to be evicted.

You may want to configure an ObjectSizer but see the object sizer section to see if the default will work for your use case.
This algorithm is your best, first choice, of the three. However the resource manager's interaction with the Java VM garbage collector can be complex which may force you to use one of the other algorithms.

For more information on the resource manager and HeapLRU see:

ObjectSizer

As of GemFire 6.5 the default object sizer is a good choice provided all the object instances cached in the evictable region have a consistent, per class, size. For example say you have a region that contains both Order objects and Employee objects. As long as the actual size of each Order is close to the average Order size and the actual size of each Employee is close to the average Employee size then the default object sizer will be a good choice.
Otherwise you should provide your own ObjectSizer implementation.

The ObjectSizer interface can be implemented when using MemoryLRU or HeapLRU. It allows GemFire to call your code when computing the size of an entry. For help on figuring out the memory overhead of your objects see this.
It is important to make your size estimates as accurate as possible but keep in mind that if you write a complex ObjectSizer which takes a long time to compute the size then the performance of your region will suffer.

Your ObjectSizer is free to call either of the implementations provided by GemFire. They are available on these static fields:

  • ObjectSizer.SIZE_CLASS_ONCE
  • ObjectSizer.REFLECTION_SIZE

If all of your entry values are String or byte[] you do not need to add an ObjectSizer because GemFire will compute the memory size of these.
For examples of how to add an ObjectSizer see this.

Eviction and Parititioned Regions

[Partitioned regions] can be configured for eviction. Each bucket of the partitioned region has its own LRU list instead of one list for the entire region.

If redundancy on the region is greater than zero and it is configured to destroy evict then it is possible for an entry to be evicted from a primary but not the secondary or from the secondary and not the primary. This is because destroys done by eviction do not do any distribution. So a read operation that goes to the primary may get a hit and one that goes to the secondary may get a miss. If you configure the region with a CacheLoader then all reads will go to the primary and it will reload entries evicted from the primary.

Warning

A partitioned region with redundancy greater than zero and destroy eviction without a CacheLoader can give inconsistent views on what entries are in the region.

Partitioned EntryLRU

The maximum entry count is the maximum total number of entries one VM can have in all of its buckets (both primary and secondary) for the partitioned region. When an addition is made that detects the limit is exceeded it is the least recently used entry of the bucket the addition is being made to that will be evicted.

Partitioned MemoryLRU

The maximum memory limit on a partitioned region is always local-max-memory. It does not matter what the maximum attribute on lru-memory-size is set to; it is always overridden by the partitioned region's local-max-memory.
When an addition is made that detects the limit is exceeded then it is the least recently used entry (or entries) of the bucket the addition is being made to that will be evicted.

Partitioned HeapLRU

When an addition is made that detects the heap limit is exceeded (by checking with the resource manager) it will remove at least as many bytes as it added to the bucket the addition is being made to. It will be the least recently used entries on that bucket that are evicted.

For more information on eviction on partitioned regions see this.

Performance


Statistics related to eviction

Statistics Overview

See Management and Monitoring for instructions on how to record statistics and tools that can analyze statistics.

Each of the following LRU statistics describe a specific region. The name of the instance will be the region name it describes.
The ResourceManagerStats and CachePerfStats are singletons for the entire cache.

Child Pages

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
Adaptavist Theme Builder (3.4.0-M2-conf210) Powered by Atlassian Confluence 2.10.3, the Enterprise Wiki.