Data Eviction

Error formatting macro: composition-setup: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil

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
Error formatting macro: deck: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC
  "-//GemStone Systems, Inc.//GemFire Declarative Cache 6.5//EN"
  "http://www.gemstone.com/dtd/cache6_5.dtd">
<cache>
  <region name="exampleRegion" refid="REPLICATE">
    <region-attributes>
       <eviction-attributes>
         <lru-entry-count maximum="76" action="local-destroy"/>
       </eviction-attributes>
    </region-attributes>
  </region>
</cache>
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil
import com.gemstone.gemfire.cache.*;
import static com.gemstone.gemfire.cache.RegionShortcut.*;
public Region createRegion(Cache cache, String name) {
  return cache.createRegionFactory(REPLICATE)
    .setEvictionAttributes(EvictionAttributes.createLRUEntryAttributes(76, EvictionAction.LOCAL_DESTROY))
    .create(name);
}
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC
  "-//GemStone Systems, Inc.//GemFire Declarative Cache 6.5//EN"
  "http://www.gemstone.com/dtd/cache6_5.dtd">
<cache>
  <region name="exampleRegion" refid="REPLICATE">
    <region-attributes>
       <eviction-attributes>
         <lru-memory-size maximum="99" action="local-destroy">
            <class-name>mypackage.MyObjectSizer</class-name>
         </lru-memory-size>
       </eviction-attributes>
    </region-attributes>
  </region>
</cache>
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil
package mypackage;
import com.gemstone.gemfire.cache.*;
import static com.gemstone.gemfire.cache.RegionShortcut.*;
import com.gemstone.gemfire.cache.util.ObjectSizer;
public class MyObjectSizer implements ObjectSizer, Declarable {
  public void init(java.util.Properties props) {
    /* initialization code goes here for cache.xml support */
  }
  public int sizeof(Object o) {
    /* simple implementation that knows all instances are 4k */
    return 4*1024;
  }
}
public Region createRegion(Cache cache, String name) {
  return cache.createRegionFactory(REPLICATE)
    .setEvictionAttributes(EvictionAttributes.createLRUMemoryAttributes(99, new MyObjectSizer(), EvictionAction.LOCAL_DESTROY))
    .create(name);
}
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil
<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC
  "-//GemStone Systems, Inc.//GemFire Declarative Cache 6.5//EN"
  "http://www.gemstone.com/dtd/cache6_5.dtd">
<cache>
  <resource-manager eviction-heap-percentage="75"/>
  <region name="exampleRegion" refid="PARTITION_HEAP_LRU"/>
</cache>
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil
import com.gemstone.gemfire.cache.*;
import static com.gemstone.gemfire.cache.RegionShortcut.*;
public void myCacheInit(Cache c) {
  // call this after the GemFire Cache has been created
  c.getResourceManager().setEvictionHeapPercentage(75);
}
public Region createRegion(Cache cache, String name) {
  return cache.createRegionFactory(PARTITION_HEAP_LRU)
    .create(name);
}

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:

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:

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:

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.

Error formatting macro: deck: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil

All three types of LRU algorithms have these statistics in common.

statistic description
lruEvictions The total number of total entry evictions triggered by LRU.
lruDestroys The number of entries destroyed in the region through both destroy cache operations and eviction. Reset to zero each time it exceeds lruDestroysLimit.
lruDestroysLimit The maximum number of entry destroys triggered by LRU before a scan occurs. Currently always 1000.
lruEvaluations The total number of entries evaluated during LRU operations.
lruGreedyReturns The total number times an entry that was not the least recently used was evicted. This will only happen if the gemfire.lru.maxSearchEntries system property is set to a value greater than zero.
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil

LRUStatistics are for regions configured with an EntryLRU.

statistic description
entriesAllowed The number of entries allowed in this region. It shows the entry limit configured on the region.
entryCount The current number of entries in this region. This should not exceed entriesAllowed.
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil

MemLRUStatistics are for regions configured with a MemoryLRU.

statistic description
bytesAllowed The amount of memory, in bytes, that this region can use before eviction starts. This is the memory limit configured on the region.
byteCount The current amount of memory, in bytes, that this region has used. This should not exceed bytesAllowed.
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil

HeapLRUStatistics are for regions configured with a HeapLRU.

statistic description
heapUsage The amount of VM heap currently in use by this region in bytes.
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil

ResourceManagerStats has the following statistics related to HeapLRU.

statistic description
evictionStartEvents The total number of times heap usage went over the eviction threshold.
evictMoreEvents The total number of times an evict more event was delivered.
evictionStopEvents The total number of times heap usage fell below the eviction threshold.
evictionThreshold The currently set eviction threshold value in bytes.
Error formatting macro: card: java.lang.NoClassDefFoundError: net/customware/confluence/plugin/composition/CompositionUtil

CachePerfStats has the following statistics related to HeapLRU. They let you see how much work is being done by the background resource manager evictor threads.

statistic description
evictorQueueSize Current number of jobs waiting to be picked up by evictor threads.
evictorJobsStarted Total number of evictor jobs started.
evictorJobsCompleted Total number of evictor jobs completed.
evictWorkTime Total time, in nanoseconds, spent doing eviction work in background threads.

Capacity Planning


Memory

The per entry memory overhead when using eviction regions is described here.

Further Information


Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.