##### Child pages
• Terracotta Distributed Cache

# Page History

## Key

• This line was removed.
• Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin
Include Page
 docs:documentation-navbardocs: documentation-navbar
Section
Column
width 250px
{div:style=} {include:
Wiki Markup
Div
style margin-top:20px
Include Page
 documentation-index documentation-index
} {div}
Column
{div9:id=documentationcolumn} {include:HeaderBasic} h1. Terracotta Cache Evictor {toc:minLevel=2|maxLevel=2} h2. Introduction The Terracotta Cache Evictor is an interface providing a simple distributed eviction solution for map elements. The Cache Evictor, implemented with the Terracotta Integration Module {{tim-map-evictor}}, provides a number of advantages over more complex solutions: * Simple -- API is easy to understand and code against. * Distributed -- Eviction is distributed along with data to maintain coherence. * Standard -- Data eviction is based on standard expiration metrics. * Lightweight -- Implementation does not hog resources. * Efficient -- Optimized for a clustered environment to minimize faulting due to low locality of reference. * Fail-Safe -- Data can be evicted even if written by a failed node or after all nodes have been restarted. * Self-Contained -- Implements a Map for optional ready-to-use distributed cache. * Native -- Designed for Terracotta to eliminate integration issues. h2. How to Implement and Configure Under the appropriate conditions, the Terracotta Cache Evictor can be used in any Terracotta cluster. If your application can use the Cache Evictor's built-in Map implementation for a cache, you can avoid having to customize your own data structure. See [#A Simple Distributed Cache] for instructions on using the Cache Evictor with the provided Map implementation. h3. Characteristics and Requirements The Terracotta Cache Evictor has the following eviction characteristics: * A Time To Live (TTL) value can be set. The TTL determines the maximum amount of time an object can remain in the cache before becoming eligible for eviction, regardless of other conditions such as use. TTL is global (applies to each element). * A Time To Idle (TTI) value can be set. The TTI determines the maximum amount of time an object can remain idle in the cache before becoming eligible for eviction. TTI is reset each time the object is used. TTI is global (applies to each element). * Each element does receive its own timestamp used against the cache-wide TTL and TTI. * "Orphaned" values (values no longer local to any node) are evicted in batches. The Terracotta Cache Evictor requires JDK 1.5 or greater. If you choose not to use the provided Map implementation, you must provide your own data structure and take the following steps: * Use a partial-loading data structure for the evictor to target (see [Clustered Data Structures Guide]). * Write start/stop thread-management code to run the evictor. * Include the code from CHMDistributedMap that performs local eviction (see the {{tim-map-evictor}} library). * Implement the Evictor interface from {{tim-map-evictor}}. See the following sections for an example of how the Terracotta Cache Evictor is intended to function with its built-in Map implementation. h3. Installing the TIM To use the Terracotta Cache Evictor, you must both install {{tim-map-evictor}} and include the evictor JAR file in your classpath. To install the TIM, run the following command from ${TERRACOTTA_HOME}: {noformat:title=UNIX/Linux} [PROMPT] bin/tim-get.sh install tim-map-evictor {noformat} {noformat:title=Microsoft Windows} [PROMPT] bin\tim-get.bat install tim-map-evictor {noformat} You should see output that appears similar to the following: {noformat} Installing tim-map-evictor 1.3.0-SNAPSHOT and dependencies... INSTALLED: tim-map-evictor 1.3.0-SNAPSHOT - Ok INSTALLED: tim-concurrent-collections 1.3.0-SNAPSHOT - Ok {noformat} Update the Terracotta configuration file ({{tc-config.xml}} by default) with the following snippet: {code:xml} <tc:tc-config xsi:schemaLocation="http://www.terracotta.org/schema/terracotta-4.xsd"> ... <clients> ... <modules> <module name="tim-map-evictor" version="1.3.0-SNAPSHOT" /> </modules> ... </clients> ... </tc:tc-config> {code} For more information about installing and updating TIMs, see the [TIM Update Center|tim-get]. h2. A Simple Distributed Cache Clustered applications with a system of record (SOR) on the backend can benefit from a distributed cache that manages certain data in memory while reducing costly application-SOR interactions. However, using a cache can introduce increased complexity to software development, integration, operation, and maintenance. The Terracotta Cache Evictor includes a distributed-map that can be used as a simple distributed cache. This cache uses the Terracotta Cache Evictor, incorporating all of its benefits. It also takes both established and innovative approaches to the caching model, solving performance and complexity issues by: * obviate SOR commits for data with a limited lifetime; * making cached application data available in-memory across a cluster of application servers; * offering standard methods for working with cache elements and performing cache-wide operations; * incorporating concurrency for readers and writers; * utilizing a flexible map implementation to adapt to more applications; * minimizing inter-node faulting to speed data operations. h3. Structure and Characteristics The Terracotta distributed cache is an interface incorporating a distributed map with standard map operations: {code} public interface DistributedMap<K, V> { // Single item operations void put(K key, V value); V get(K key); V remove(K key); boolean containsKey(K key); // Multi item operations int size(); void clear(); Set<K> getKeys(); // For managing the background evictor thread void start(); void shutdown(); } {code} {tip} getValues() is not provided, but an iterator can be obtained for Set<K> to obtain values. {tip} {comment} * The map containing the timestamps is clustered, allowing all nodes to be aware of expirations and pending evictions. {comment} h3. Usage Pattern A typical usage pattern for the Terracotta Cache Evictor is shown in the MyStuff class below. The next section contains a full list of configuration parameters available to {{DistributedMapBuilder}}. {code:java} import org.terracotta.modules.dmap.DistributedMap; import org.terracotta.modules.dmap.DistributedMapBuilder; import static org.terracotta.modules.dmap.DistributedMapBuilder.HOUR; import static org.terracotta.modules.dmap.DistributedMapBuilder.MINUTE; public class MyStuff { // Mark as Terracotta root private DistributedMap<String, Stuff> sharedMap; public MyStuff() { if(sharedMap == null) { DistributedMap<String,Stuff> newMap = new DistributedMapBuilder() .setMaxTTLMillis(6*HOUR) // regardless of use, remove after 6 hours .setMaxTTIMillis(30*MINUTE) // remove after 30 minutes of unuse .setEvictorSleepMillis(5*MINUTE) // only do eviction every 5 minutes .newMap(); // set root - if this doesn't succeed, shutdown the newMap as it has a worthless background evictor thread sharedMap = newMap; if(sharedMap != newMap) { newMap.shutdown(); } } public void putStuff(String key, Stuff stuff) { sharedMap.put(key, stuff); } public Stuff getStuff(String key) { return sharedMap.get(key); } } {code} h4. Evictor Configuration Parameters ||Config property || Default value || Description || |name | "Distributed Map" | A descriptive string used in log messages and evictor thread names. | |concurrency | 16 | The maximum number of concurrent threads that can access the map. | |maxTTIMillis | 0 | Time To Idle - the maximum amount of time (in milliseconds) an item can be in the map unused before expiration; 0 means never expire due to TTI. | |maxTTLMillis | 0 | Time To Live - the maximum amount of time (in milliseconds) an item may be in the map regardless of use before expiration; 0 means never expire due to TTL. | |evictorSleepMillis | 30000 | Wait time (in milliseconds) between eviction cycles; should be tuned to work well with TTI/TTL values. | |orphanEvictionEnabled | true | Determines whether "orphaned" values (values no longer local to any node) are evicted. | |orphanEvictionFrequency | 4 | Number of times to run local eviction between doing orphan eviction. | |orphanBatchSize | 1000 | Size of each set of items evicted during orphan eviction. | |orphanBatchPauseMillis | 20 | Rest time (in milliseconds) between each orphan batch eviction. | |loggingEnabled | false | Basic distributed-map logging messages saved to the Terracotta logs. | |evictorLoggingEnabled | false | Eviction logging messages saved to the Terracotta logs.. | h3. Usage Example The following is an example of a cache that implements the Terracotta distributed cache: {code} import org.terracotta.modules.dmap Wiki Markup Div id documentationcolumn Include Page  HeaderBasic HeaderBasic Note title D E P R E C A T E D The Terracotta Distributed Cache based on the Terracotta Integration Module (TIM) tim-distributed-cache has been deprecated in favor of the HTML <a href="/documentation/ga/product-documentation">Terracotta Distributed Ehcache</a> . # Terracotta Distributed Cache Table of Contents  minLevel 2 2 ## Introduction The Terracotta Distributed Cache is an interface providing a simple distributed eviction solution for map elements. The Distributed Cache, implemented with the Terracotta Integration Module (TIM) tim-distributed-cache, provides a number of advantages over more complex solutions: • Simple – API is easy to understand and code against. • Distributed – Eviction is distributed along with data to maintain coherence. • Standard – Data eviction is based on standard expiration metrics. • Lightweight – Implementation does not hog resources. • Efficient – Optimized for a clustered environment to minimize faulting due to low locality of reference. • Fail-Safe – Data can be evicted even if written by a failed node or after all nodes have been restarted. • Self-Contained – Implements a Map for optional ready-to-use distributed cache. • Native – Designed for Terracotta to eliminate integration issues. ## How to Implement and Configure Under the appropriate conditions, the Terracotta Distributed Cache can be used in any Terracotta cluster. If your application can use the Distributed Cache's built-in Map implementation for a cache, you can avoid having to customize your own data structure. See #A Simple Distributed Cache for instructions on using the Distributed Cache with the provided Map implementation. ### Requirements To ensure that the Terracotta Distributed Cache performs well and without errors, check the following requirements. #### Classpath Requirements The TIMs tim-distributed-cache and tim-concurrent-collections must be on your application's classpath at runtime. See #Installing the TIM to learn how to install tim-distributed-cache. Tip When you install tim-distributed-cache, tim-concurrent-collections is automatically installed. #### Eviction Parameters The Terracotta Distributed Cache has the following eviction parameters: Time to Live The Time to Live (TTL) value determines the maximum amount of time an object can remain in the cache before becoming eligible for eviction, regardless of other conditions such as use. Time to Idle The Time to Idle (TTI) value determines the maximum amount of time an object can remain idle in the cache before becoming eligible for eviction. TTI is reset each time the object is used. Target Max In-Memory Count The in-memory count is the maximum number of elements allowed in a region in any one client (any one application server). If this target is exceeded, eviction occurs to bring the count within the allowed target. The flexibility of using a target as opposed to hard limit serves to improve concurrency. 0 means no eviction takes place (infinite size is allowed). Target Max Total Count The total count is the maximum total number of elements allowed for a region in all clients (all application servers). If this target is exceeded, eviction occurs to bring the count within the allowed target. The flexibility of using a target as opposed to hard limit serves to improve concurrency. 0 means no eviction takes place (infinite size is allowed). To maximize cache performance benefits, configure and tune these parameters to optimize data retention and eviction behavior. To learn how to configure the Terracotta Distributed Cache eviction parameters, see #Usage Pattern. #### JDK Version The Terracotta Distributed Cache requires JDK 1.5 or greater. ### Installing the TIM To use the Terracotta Distributed Cache, you must both install tim-distributed-cache and include the evictor JAR file in your classpath. To install the TIM, run the following command from${TERRACOTTA_HOME}:

No Format
title UNIX/Linux

[PROMPT] bin/tim-get.sh install tim-distributed-cache

No Format
title Microsoft Windows

[PROMPT] bin\tim-get.bat install tim-distributed-cache


You should see output that appears similar to the following:

No Format

Installing tim-distributed-cache 1.3.0-SNAPSHOT and dependencies...
INSTALLED: tim-distributed-cache 1.3.0-SNAPSHOT - Ok
INSTALLED: tim-concurrent-collections 1.3.0-SNAPSHOT - Ok


Run the following command from \${TERRACOTTA_HOME} to update the Terracotta configuration file (tc-config.xml by default):

No Format
title UNIX/Linux


No Format
title Microsoft Windows



### Locking Requirements

Terracotta automatically provides locking for read (get) and write (put) operations on the distributed map. These locks last for the duration of the get or put operation.

Mutating an object obtained from the distributed map requires a read/write lock to avoid race conditions and potential corruption to data.

For example, assume a distributed map has an element <k1, v1> in it. The following operation does not require explicit locking:

Code Block

myObject = getFromMyDistributedMap(k1); // Terracotta provides a lock for the duration of getFromMyDistributedMap().


Adding a new element to the map also does not require explicit locking:

Code Block

putIntoMyDistributedMap(k2, v2); // Terracotta provides a lock for the duration of putIntoMyDistributedMap().


However, the following operation requires a read/write lock:

Code Block

myNewObject = myMutator(myObject); // myObject should be locked until it is put back into the map.


Note the following:

• To be shared across the cluster, the myObject field must be declared a Terracotta root or its class (its type) must be instrumented.
• Cluster-wide locking (Terracotta locking) must be present when myMutator() changes myObject. There are several ways to implement Terracotta locking.
• To gain visibility into the cluster and better understand how the map and object graphs are being clustered, use the Terracotta Developer Console's Object Browser.
• Use the Terracotta Developer Console's Lock Profiler to see what locks are being used and their usage patterns.
Info

For more information on locks, Terracotta roots, and instrumenting classes, see the following resources:

For more information on the Terracotta Developer Console, see the console guide.

## A Simple Distributed Cache

Clustered applications with a system of record (SOR) on the backend can benefit from a distributed cache that manages certain data in memory while reducing costly application-SOR interactions. However, using a cache can introduce increased complexity to software development, integration, operation, and maintenance.

The Terracotta Distributed Cache includes a distributed Map that can be used as a simple distributed cache. This cache uses the Terracotta Distributed Cache, incorporating all of its benefits. It also takes both established and innovative approaches to the caching model, solving performance and complexity issues by:

• obviating SOR commits for data with a limited lifetime;
• making cached application data available in-memory across a cluster of application servers;
• offering standard methods for working with cache elements and performing cache-wide operations;
• incorporating concurrency for readers and writers;
• utilizing a flexible map implementation to adapt to more applications;
• minimizing inter-node faulting to speed data operations.

### Structure and Characteristics

The Terracotta Distributed Cache is an interface incorporating a distributed map (an extension of ConcurrentMap in the JDK) with standard map operations. For more information about the Terracotta Distributed Cache, see:

Tip

getValues() is not provided, but an iterator can be obtained for Set<K> to obtain values.

comment

* The map containing the timestamps is clustered, allowing all nodes to be aware of expirations and pending evictions.


### Usage Pattern

A typical usage pattern for the Terracotta Distributed Cache is shown in the MyStuff class below. The next section contains a full list of configuration parameters available to CacheConfigFactory.

Code Block
 java java

import org.terracotta.cache.CacheConfigFactory;
import org.terracotta.cache.DistributedCache;

public class MyStuff {

// Mark as Terracotta root
private DistributedCache<String, Stuff> sharedCache;

public MyStuff() {
if(sharedCache == null) {
DistributedCache<String, Stuff> newCache =
CacheConfigFactory.newConfig()
.setMaxTTLSeconds(6*60 * 60) // Regardless of use, remove after 6 hours
.setMaxTTISeconds(30*60) // Remove after 30 minutes of none-use.
.newCache();

// Set root - if this doesn't succeed, shutdown the newCache as it has a worthless background evictor thread.
sharedCache = newCache;
if(sharedCache != newCache) {
newCache.shutdown();
}
}

public void putStuff(String key, Stuff stuff) {
sharedCache.put(key, stuff);
}

public Stuff getStuff(String key) {
return sharedCache.get(key);
}
}


#### Cache Configuration Parameters

The configuration parameters that can be set through CacheConfigFactory are summarized in the following table.

Config property

Default value

Description

name

"Distributed Map"

A descriptive string used in log messages and evictor thread names.

maxTTISeconds

0

Time To Idle - the maximum amount of time (in seconds) an item can be in the map unused before expiration; 0 means never expire due to TTI.

maxTTLSeconds

0

Time To Live - the maximum amount of time (in seconds) an item may be in the map regardless of use before expiration; 0 means never expire due to TTL.

orphanEvictionEnabled

true

Determines whether "orphaned" values (values no longer local to any node) are evicted.

orphanEvictionPeriod

4

Number of times to run local eviction between doing orphan eviction.

loggingEnabled

false

Basic distributed-map logging messages saved to the Terracotta logs.

targetMaxInMemoryCount

0

Target maximum number of values stored in memory for a region on any Terracotta client (application server). If target is exceeded, elements are flushed to a Terracotta server instance but not evicted. The default of 0 gives elements an infinite lifetime.

targetMaxTotalCount

0

Target maximum number of values stored for a region in the cluster. If the target is exceeded, elements are evicted to bring the total back under the limit. The default of 0 gives elements an infinite lifetime.

### Usage Example

The following is an example of a cache that implements the Terracotta distributed cache:

Code Block

import org.terracotta.cache.*;
import static org.terracotta.
modules
 cache.
dmap.DistributedMapBuilder
 CacheConfigFactory.*; 
DisributedMap<String
 DisributedCache
map
 cache =
new DistributedMapBuilder
 CacheConfigFactory.newConfig() .
setMaxTTLMillis
 setMaxTTLSeconds(10
* SECOND
 ) .
setMaxTTIMillis
 setMaxTTISeconds(5
* SECOND) .setConcurrency(16
 )
.newMap();
  
map
 .
start
 newCache(); // start
 () method not needed; start is automatic. cache.put("Rabbit", "Carrots"); 
map
 cache.put("Dog", "Bone"); 
map
 cache.put("Owl", "Mouse"); // wait 3 seconds 
map
 cache.get("Rabbit"); // wait 2 seconds - expire Dog and Owl due to TTI assert ! 
map
 cache.containsKey("Dog"); assert ! 
map
 cache.containsKey("Owl"); assert 
map
 cache.containsKey("Rabbit"); // wait 5 seconds - expire Rabbit due to TTL assert ! 
map
 cache.containsKey("Rabbit"); 
{code} h2. Terracotta Cache Evictor in a Reference Application The [Examinator reference application|orgsite:Web App Reference Implementation] uses the Terracotta Cache Evictor to handle pending user registrations. This type of data has a

## Terracotta Distributed Cache in a Reference Application

The Examinator reference application uses the Terracotta Distributed Cache to handle pending user registrations. This type of data has a "medium-term"

which

needs

to

be

persisted

long

enough

to

give

prospective

registrants

a

chance

to

verify

their

registrations.

If

a

registration

isn't

verified

by

the

time

TTL

is

reached,

it

can

be

evicted

from

the

cache.

Only

if

the

registration

is

verified

is

it

written

to

the

database.

The

combination

of

Terracotta

and

the

Terracotta

Distributed Cache

Evictor

gives

Examinator

the

following

*

• The
• simple
• Terracotta
• Distributed Cache
Evictor
• 's
• API
• makes
• it
• easy
• to
• integrate
• with
• Examinator
• and
• to
• maintain
• and
• troubleshoot.
*
• Medium-term
• data
• is
• not
• written
• to
• the
• database
• unnecessarily,
• improving
• application
• performance.
*
• Terracotta
• persists
• the
• pending
• registrations
• so
• they
• can
• survive
• node
• failure.
*
• Terracotta
• clusters
• (shares)
• the
• pending
• registration
• data
• so
• that
• any
• node
• can
• handle
• validation.
{div9}