This site hosts historical documentation. Visit www.terracotta.org for recent product information.
When using BigMemory Go through its Ehcache API, many aspects of the data storage tiers can be controlled through the Ehcache configuration.
The memory store is the top tier and is automatically used by BigMemory Go to store the data hotset because it is the fastest store. It requires no special configuration to enable, and its overall size is taken from the Java heap size. Since it exists in the heap, it is limited by Java GC constraints.
All caches specify their maximum in-memory size, in terms of the number of elements, at configuration time.
When an element is added to a cache and it goes beyond its maximum
memory size, an existing element is either deleted, if overflow
is not enabled, or evaluated for spooling to another tier, if overflow is enabled. The overflow options are overflowToOffHeap
and <persistence>
(disk store).
If overflow is enabled, a check for expiry is carried out. If it is expired
it is deleted; if not it is spooled. The eviction of an item from
the memory store is based on the optional MemoryStoreEvictionPolicy
attribute
specified in the configuration file. Legal values are LRU (default), LFU and FIFO:
For all the eviction policies there are also putQuiet
and getQuiet
methods which do not update the last used timestamp.
When there is a get
or a getQuiet
on an element, it is checked for expiry. If expired, it is removed and null is returned. Note that at any point in time there will usually be some expired elements in the cache. Memory sizing of an application must always take into
account the maximum size of each cache.
calculateInMemorySize() is a convenient method which can provide an estimate of the size (in bytes) of the memory store. It returns the serialized size of the cache, providing a rough estimate. Do not use this method in production as it is has a negative effect on performance. |
An alternative would be to have an expiry thread. This is a trade-off between lower memory use and short locking periods and CPU utilization. The design is in favour of the latter. For those concerned with memory use, simply reduce the cache's size in memory for more information).
If an off-heap store is configured, the corresponding memory store overflows to that off-heap store. Configuring an off-heap store can be done either through XML or programmatically. With either method, the off-heap store is configured on a per-cache basis.
The following XML configuration creates an off-heap cache with an in-heap store (maxEntriesLocalHeap) of 10,000 elements which overflow to a 1-gigabyte off-heap area.
<ehcache updateCheck="false" monitoring="off" dynamicConfig="false">
<defaultCache maxEntriesLocalHeap="10000"
eternal="true"
memoryStoreEvictionPolicy="LRU"
statistics="false" />
<cache name="sample-offheap-cache"
maxEntriesLocalHeap="10000"
eternal="true"
memoryStoreEvictionPolicy="LRU"
overflowToOffHeap="true"
maxBytesLocalOffHeap="1G"/>
</ehcache>
The configuration options are:
Values may be true or false. When set to true, enables the cache to utilize off-heap memory storage to improve performance. Off-heap memory is not subject to Java GC cycles and has a size limit set by the Java property MaxDirectMemorySize. The default value is false.
Sets the amount of off-heap memory available to the cache and is in effect only if overflowToOffHeap
is tr
ue. The minimum amount that can be allocated is 1MB. There is no maximum.
For more information on sizing data stores, refer to this page.
You should set maxEntriesLocalHeap to at least 100 elements when using an off-heap store to avoid performance degradation. Lower values for maxEntriesLocalHeap trigger a warning to be logged. |
The equivalent cache can be created using the following programmatic configuration:
public Cache createOffHeapCache()
{
CacheConfiguration config = new CacheConfiguration("sample-offheap-cache", 10000)
.overflowToOffHeap(true).maxBytesLocalOffHeap("1G");
Cache cache = new Cache(config);
manager.addCache(cache);
return cache;
}
Disk stores are configured on a per CacheManager basis. If one or more caches requires a disk store but none is configured, a default directory is used and a warning message is logged to encourage explicit configuration of the disk store path.
Configuring a disk store is optional. If all caches use only memory and off-heap stores, then there is no need to configure a disk store. This simplifies configuration, and uses fewer threads. This also makes it unnecessary to configure multiple disk store paths when multiple CacheManagers are being used.
Two disk store options are available:
See the following sections for more information on these options.
The "localTempSwap" persistence strategy allows local disk usage during BigMemory operation, providing an extra tier for storage. This disk storage is temporary and is cleared after a restart.
If the disk store path is not specified, a default path is used, and the default will be auto-resolved in the case of a conflict with another CacheManager.
The localTempSwap disk store creates a data file for each cache on startup called "<cache_name>
.data".
This option implements a restartable store for all in-memory data. After any restart, the data set is automatically reloaded from disk to the in-memory stores.
The path to the directory where any required disk files will be created is configured with the <diskStore>
sub-element of the Ehcache configuration. In order to use the restartable store, a unique and explicitly specified path is required.
Files are created in the directory specified by the <diskStore>
configuration element. The <diskStore>
element has one attribute called path
.
<diskStore path="/path/to/store/data"/>
Legal values for the path attibute are legal file system paths. For example, for Unix:
/home/application/cache
The following system properties are also legal, in which case they are translated:
java -Dehcache.disk.store.dir=/u01/myapp/diskdir
.Subdirectories can be specified below the system property, for example:
user.dir/one
To programmatically set a disk store path:
DiskStoreConfiguration diskStoreConfiguration = new DiskStoreConfiguration();
diskStoreConfiguration.setPath("/my/path/dir");
// Already created a configuration object ...
configuration.addDiskStore(diskStoreConfiguration);
CacheManager mgr = new CacheManager(configuration);
Note: A CacheManager's disk store path cannot be changed once it is set in configuration. If the disk store path is changed, the CacheManager must be recycled for the new path to take effect.
Expired elements are eventually evicted to free up disk space. The element is also removed from the in-memory index of elements.
One thread per cache is used to remove expired elements. The optional attribute diskExpiryThreadIntervalSeconds
sets the interval between runs of the expiry thread.
Warning: Setting diskExpiryThreadIntervalSeconds
to a low value can cause excessive disk-store locking and high CPU utilization. The default value is 120 seconds.
If a cache's disk store has a limited size, Elements will be evicted from the disk store when it exceeds this limit. The LFU algorithm is used for these evictions. It is not configurable or changeable.
Note: With the "localTempSwap" strategy, you can use maxEntriesLocalDisk
or maxBytesLocalDisk
at either the Cache or CacheManager level to control the size of the swap-to-disk area.
To turn off disk store path creation, comment out the diskStore
element in ehcache.xml.
The default Ehcache configuration, ehcache-failsafe.xml, uses a disk store. To avoid use of a disk store, specify a custom ehcache.xml with the diskStore
element commented out.
These examples show how to allocate 8GB of machine memory to different stores. It assumes a data set of 7GB - say for a cache of 7M items (each 1kb in size).
Those who want minimal application response-time variance (or minimizing GC pause times), will likely want all the cache to be off-heap. Assuming that 1GB of heap is needed for the rest of the app, they will set their Java config as follows:
java -Xms1G -Xmx1G -XX:maxDirectMemorySize=7G
And their Ehcache config as:
<cache maxEntriesLocalHeap=100 overflowToOffHeap="true" maxBytesLocalOffHeap="6G" ... />
To accommodate server communications layer requirements, the value of maxDirectMemorySize must be greater than the value of maxBytesLocalOffHeap. The exact amount greater depends upon the size of maxBytesLocalOffHeap. The minimum is 256MB, but if you allocate 1GB more to the maxDirectMemorySize, it will certainly be sufficient. The server will only use what it needs and the rest will remain available. |
Those who want best possible performance for a hot set of data, while still reducing overall application repsonse time variance, will likely want a combination of on-heap and off-heap. The heap will be used for the hot set, the offheap for the rest. So, for example if the hot set is 1M items (or 1GB) of the 7GB data. They will set their Java config as follows
java -Xms2G -Xmx2G -XX:maxDirectMemorySize=6G
And their Ehcache config as:
<cache maxEntriesLocalHeap=1M overflowToOffHeap="true" maxBytesLocalOffHeap="5G" ...>
This configuration will compare VERY favorably against the alternative of keeping the less-hot set in a database (100x slower) or caching on local disk (20x slower).
Where the data set is small and pauses are not a problem, the whole data set can be kept on heap:
<cache maxEntriesLocalHeap=1M overflowToOffHeap="false" ...>
Where latency isn't an issue, the disk can be used:
<cache maxEntriesLocalHeap=1M <persistence strategy="localTempSwap"/> ...>