This document contains reference information on the Terracotta Distributed Cache.
The Terracotta Distributed Ehcache configuration file (
ehcache.xml
by default) contains the configuration for one instance of a CacheManager (the Ehcache class managing a set of defined caches). This configuration file must be in your application's classpath to be found. When using a WAR file,
ehcache.xml
should be copied to
WEB-INF/classes
.
Certain elements in the Ehcache configuration control the clustering of caches with Terracotta.
This element is an optional sub-element of <cache>. It can be set differently for each <cache> defined in
ehcache.xml
.
<terracotta> has the following attributes:
serialization
(DEFAULT, the standard Ehcache "copy" cache) or
identity
(Terracotta object identity).
Identity mode is not available with the express installation
.
Identity mode can be used only with a custom Terracotta installation
(see Express Versus Custom Installations).|
In serialization mode, getting an element from the cache gets a copy of that element. Changes made to that copy do not affect any other copies of the same element or the value in the cache. Putting the element in the cache overwrites the existing value. This type of cache provides high performance with small, read-only data sets. Large data sets with high traffic, or caches with very large elements, can suffer performance degradation because this type of cache serializes clustered objects. In read-write data sets, data coherency issues may arise because this type of cache cannot guarantee a consistent view of object values. Objects clustered in this mode _must be_ serializable.
In identity mode, getting an element from the cache gets a reference to that element. Changes made to the referenced element updates the element on every node on which it exists (or a reference to it exists) as well as updating the value in the cache. Putting the element in the cache does not overwrite the existing value. This mode guarantees data coherence. It can be used only with a custom Terracotta Distributed Cache installation. Objects clustered in this mode must be
portable
and must be locked when accessed. If you require identity mode, you must use DSO (see Terracotta Custom Installation).
|
When enabled, cache values are deserialized (copied) on every read and the materialized values are not re-used between get() calls; each get()call returns a unique reference. When enabled, this setting allows Ehcache to behave as a component of OSGI, allows a cache to be shared by callers with different classloaders, and prevents local drift if keys/values are mutated locally without being put back into the cache. Enabling copyOnRead is relevant only for caches with valueMode set to serialization .
The following attributes are used with Terracotta Distributed Ehcache for Hibernate:
This element can not be used with a DSO installation (see Express Versus Custom Installations). It enables the client to identify the source of configuration. The client must load the configuration from a file or a Terracotta server. The value of the
url
attribute should contain a path to the file or the address and DSO port (9510 by default) of a server. In the example value, "localhost:9510" means that the Terracotta server is on the local host.
For more information on client configuration, see the Clients Configuration Section in the Terracotta Configuration Guide and Reference .
Add the
url
attribute to the <terracottaConfig> element as follows:
<terracottaConfig url="<source>" />
where <source> must be one of the following:
url="/path/to/tc-config.xml"
)
url="http://www.mydomain.com/path/to/tc-config.xml
)
<host>:<dso-port>
(for example,
url="host1:9510"
)Note the following about using server addresses in the form <host>:<dso-port>:
You can embed the contents of a Terracotta configuration file in
ehcache.xml
as follows:
<terracottaConfig>
<tc-config>
<servers>
<server host="server1" name="s1"/>
<server host="server2" name="s2"/>
</servers>
<clients>
<logs>app/logs-%i</logs>
</clients>
</tc-config>
</terracottaConfig>
Note that not all elements are supported. For example, the <dso> section of a Terracotta configuration file is ignored in an Ehcache configuration file.
The <cache> subelement <cacheEventListenerFactory>, which registers listeners for cache events such as puts and updates, has a notification scope controlled by the attribute
listenFor
. This attributed can have one of the following values:
In order for cache events to be detected by remote nodes in a Terracotta cluster, event listeners must have a scope that includes remote events. For example, the following configuration allows listeners of type MyCacheListener to detect both local and remote events:
<cache name="myCache" maxElementsInMemory="1000"
maxElementsOnDisk="10000" eternal="false" timeToIdleSeconds="3600"
timeToLiveSeconds="0" memoryStoreEvictionPolicy="LFU">
<!-- Not defining the listenFor attribute for <cacheEventListenerFactory> is by default equivalent to listenFor="all". -->
<cacheEventListenerFactory class="net.sf.ehcache.event.TerracottaCacheEventReplicationFactory" />
<terracotta />
</cache>
You must use
net.sf.ehcache.event.TerracottaCacheEventReplicationFactory
as the factory class to enable cluster-wide cache-event broadcasts in a Terracotta cluster.
For any clustered cache, you must delete, disable, or edit configuration elements in
ehcache.xml
that are incompatible when clustering with Terracotta. Clustered caches have a <terracotta /> or <terracotta clustered="true"> element.
The following Ehcache configuration attributes or elements should be deleted or disabled:
overflowToDisk
and
diskPersistent
.The Terracotta server automatically provides a disk store.
replicateAsynchronously
and
replicatePuts
.
MemoryStoreEvictionPolicy
must be set to either LFU or LRU.
Setting
MemoryStoreEvictionPolicy
to FIFO causes the error
IllegalArgumentException
.
See the Ehcache documentation for more information on the elements in a standard Ehcache configuration file.
The Terracotta Distributed Ehcache cluster events API provides access to Terracotta cluster events and cluster topology.
The interface
net.sf.ehcache.cluster.CacheCluster
provides methods for obtaining topology information for a Terracotta cluster. The following table lists these methods.
|
Returns a scheme name for the cluster information. Currently TERRACOTTA is the only scheme supported. The scheme name is used by
CacheManager.getCluster()
to return cluster information (see Events API Example Code). |
|
The interface
net.sf.ehcache.cluster.ClusterNode
provides methods for obtaining information on specific Terracotta nodes in the cluster. The following table lists these methods.
The interface
net.sf.ehcache.cluster.ClusterTopologyListener
provides methods for detecting the following cluster events:
// Get cluster data
CacheManager mgr = new CacheManager(); // Local ehcache.xml exists, with at least one cache configured with Terracotta clustering.
CacheCluster cluster = mgr.getCluster("TERRACOTTA");
// Get current nodes
Collection<ClusterNode> nodes = cluster.getNodes();
for(ClusterNode node : nodes) {
System.out.println(node.getId() + " " + node.getHostname() + " " + node.getIp());
}
// Register listener
cluster.addTopologyListener(new ClusterTopologyListener() {
public void nodeJoined(ClusterNode node) { System.out.println(node + " joined"); }
public void nodeLeft(ClusterNode node) { System.out.println(node + " left"); }
public void clusterOnline(ClusterNode node) { System.out.println(node + " enabled"); }
public void clusterOffline(ClusterNode node) { System.out.println(node + " disabled"); }
});
The Distributed Ehcache cache coherence API can optimize certain cache operations, including bulk-loading of caches, by removing the requirement of locks and adding transaction batching. The cache coherence API allows applications to:
The initial coherence mode of a cache can also be set by configuration. See the attribute "coherent" in <terracotta>.
The following table lists the cache coherence API methods that are available by implementing the interface
org.terracotta.modules.ehcache.coherence.CacheCoherence
.
Note the following about the cache coherence API:
isCoherent()
can return true in one node just before another node calls
setCoherent(false)
on the same cache. Understanding exactly how your application uses the coherence API is crucial to effectively managing the integrity of cached data.The following example code shows how a clustered application with Terracotta Distributed Ehcache can use the cache coherence API to optimize a bulk-load operation.
The following is a simple example of a class that uses the cache coherence API to optimize loading a cache:
import net.sf.ehcache.Cache;
public class MyBulkLoader {
CacheManager cacheManager = new CacheManager(); // Assumes local ehcache.xml.
Cache cache = cacheManager.getEhcache("myCache"); // myCache defined in ehcache.xml.
cache.setCoherent(false); // myCache is now not coherent.
// Load data into myCache.
cache.setCoherent(true); // Done, now set myCache back to being coherent.
}
On another node, application code that intends to touch myCache can run or wait, based on whether myCache is coherent or not:
...
if (cache.isCoherent()) {
// Do some work.
}
else {
cache.waitUntilCoherent()
// Do the work when waitUntilCoherent() returns.
}
...
Waiting may not be necessary if the code can handle potentially stale data:
...
if (cache.isCoherent()) {
// Do some work.
}
else {
// Do some work knowing that data in myCache may be stale.
}
...
Certain environments require coherent cached data while also desiring optimized reads of cache data. If applications that read data from a coherent cache can tolerate getting potentially stale data, an unlocked (non-coherent) reads view, UnlockedReadsView, can be created for Cache types. UnlockedReadsView requires Ehcache 2.1 or higher and requires the underlying cache have Terracotta clustering. For example:
<cache name="myCache"
maxElementsInMemory="500"
eternal="false"
overflowToDisk="false"
<terracotta clustered="true"/>
</cache>
You can create an unlocked view of myCache programmatically:
Cache cache = cacheManager.getEhcache("myCache");
UnlockedReadsView unlockedReadsView = new UnlockedReadsView(cache, "myUnlockedCache");
The following table lists the API methods that are available by with
net.sf.ehcache.constructs.unlockedreadsview.UnlockedReadsView
.
The NonStopCache API allows certain cache operations to proceed on clients that have become disconnected from the cluster. Applications can use this non-blocking API to create a local cache, based on an existing cache, in the following way:
Cache cache = cacheManager.getEhcache("myCache");
NonStopCache nonStopCache = new NonStopCache(cache, "myNonStopCache");
myNonStopCache is a local cache using the same backing store as myCache. To enable access to myNonStopCache in the CacheManager scope, add myNonStopCache to a CacheManager:
cacheManager.addDecoratedCache(nonStopCache);
NonStopCache types can be configured with the following attributes:
timeoutBehavior
. This
timeoutMillis
expires). The response can be set to one of the values listed in the following table:
timeoutMillis
, so that the option set in
timeoutBehavior
is in effect immediately. You can tune the default timeout values and behaviors of NonStopCache to fit your environment.
For example, in an environment with regular network interruptions, consider disabling
immediateTimeout
and increasing
timeoutMillis
to prevent timeouts for most of the interruptions.
For a cluster that experiences regular but short network interruptions, and in which caches clustered with Terracotta carry read-mostly data or there is tolerance of potentially stale data, you may want to set
timeoutBehavior
to
localReads
.
In an environment where cache operations can be slow to return and data is required to always be in sync, increase
timeoutMillis
to prevent frequent timeouts. Set
timeoutBehavior
to
noop
to force the application to get data from another source or
exception
if the application should stop.
NonStopCaches are configured in a <cache> block using <cacheDecoratorFactory> elements. Use one <cacheDecoratorFactory> element for each NonStopCache you want to make available for a cache. In the following example, myCache has more than one NonStopCache configuration available:
<cache name="myCache" maxElementsInMemory="10000" eternal="false"
overflowToDisk="false">
<cacheDecoratorFactory
class="net.sf.ehcache.constructs.nonstop.NonStopCacheDecoratorFactory"
properties="name=nonStopCache" />
<cacheDecoratorFactory
class="net.sf.ehcache.constructs.nonstop.NonStopCacheDecoratorFactory"
properties="name=nonStopNoopCache, timeoutBehavior=noop, timeoutMillis=10000, immediateTimeout=false" />
<cacheDecoratorFactory
class="net.sf.ehcache.constructs.nonstop.NonStopCacheDecoratorFactory"
properties="name=nonStopLocalReadsCache, timeoutBehavior=localReads, timeoutMillis=4000, immediateTimeout=false" />
<terracotta />
</cache>
Application nodes can instantiate any combination of the NonStopCaches configured for myCache.
You can programmatically configure a NonStopCache either by using the NonStopCache API directly or by passing a standard Java Properties object.
Use
NonStopCacheConfigImpl()
to create the NonStopCache configuration and pass it to the NonStopCache:
NonStopCacheConfig config = new NonStopCacheConfigImpl(); // This creates a config with default values.
config.setTimeoutMillis(10000); // Customize other parameters similarly: config.setXXX(..)
NonStopCache nonStopCache = new NonStopCache(cache, "myNonStopCache", config); // Note that the name of the NonStopCache cannot be set using NonStopCacheConfig.
You can also pass a Properties object to NonStopCacheConfig:
Properties properties = new Properties();
properties.setProperty("timeoutMillis", "1000"); // Customize other parameters similarly: properties.setProperty(...).
NonStopCacheConfig config = new NonStopCacheConfigImpl(properties);
NonStopCache nonStopCache = new NonStopCache(cache, "myNonStopCache", config); // Note that the name of the NonStopCache cannot be set using NonStopCacheConfig.
If your application uses the write-behind API with Ehcache and you cluster Ehcache with Terracotta, the write-behind queue automatically becomes a clustered write-behind queue. The clustered write-behind queue features the following characteristics:
The write-behind queue is enabled for a cache with the <cacheWriter /> element. See the Ehcache documentation for more information on the write-behind API.
Terracotta Distributed Ehcache caches can participate in Java Transaction API (JTA) transactions with an isolation level of ReadCommitted. Terracotta Distributed Ehcache transactions are fully XA compliant and are tested with the most common transaction managers by Atomikos, Bitronix, JBoss, WebLogic, and others.
To allow Terracotta Distributed Ehcache to participate in JTA transactions, the following <cache> attribute must be set as shown:
In addition, the <cache> subelement <terracotta> must have the following attributes set as shown:
For more information on working with transactional caches in Terracotta Distributed Ehcache for Hibernate, see Setting Up Transactional Caches.