9.2. Configuration
Cache loaders are configured as follows in the JBoss Cache XML file. Note that you can define several cache loaders, in a chain. The impact is that the cache will look at all of the cache loaders in the order they've been configured, until it finds a valid, non-null element of data. When performing writes, all cache loaders are written to, except if the
ignoreModifications
element has been set to true
for a specific cache loader. See the configuration section below for details.
... <!-- Cache loader config block --> <!-- if passivation is true, only the first cache loader is used; the rest are ignored --> <loaders passivation="false" shared="false"> <preload> <!-- Fqns to preload --> <node fqn="/some/stuff"/> </preload> <!-- if passivation is true, only the first cache loader is used; the rest are ignored --> <loader class="org.jboss.cache.loader.JDBCCacheLoader" async="false" fetchPersistentState="true" ignoreModifications="false" purgeOnStartup="false"> <properties> cache.jdbc.driver=com.mysql.jdbc.Driver cache.jdbc.url=jdbc:mysql://localhost:3306/jbossdb cache.jdbc.user=root cache.jdbc.password= </properties> </loader> </loaders>
The
class
element defines the class of the cache loader implementation. (Note that, because of a bug in the properties editor in EAP, backslashes in variables for Windows file names might not get expanded correctly, so replace="false" may be necessary). Note that an implementation of cache loader has to have an empty constructor.
The
properties
element defines a configuration specific to the given implementation. The file system-based implementation for example defines the root directory to be used, whereas a database implementation might define the database URL, name and password to establish a database connection. This configuration is passed to the cache loader implementation via CacheLoader.setConfig(Properties)
. Note that backspaces may have to be escaped.
preload
allows us to define a list of nodes, or even entire subtrees, that are visited by the cache on start up, in order to preload the data associated with those nodes. The default ("/") loads the entire data available in the back end store into the cache, which is probably not a good idea given that the data in the back end store might be large. As an example, /a, /product/catalogue
loads the subtrees /a
and /product/catalogue
into the cache, but nothing else. Anything else is loaded lazily when accessed. Preloading makes sense when one anticipates using elements under a given subtree frequently. .
fetchPersistentState
determines whether or not to fetch the persistent state of a cache when joining a cluster. Only one configured cache loader may set this property to true; if more than one cache loader does so, a configuration exception will be thrown when starting your cache service.
async
determines whether writes to the cache loader block until completed, or are run on a separate thread so writes return immediately. If this is set to true, an instance of org.jboss.cache.loader.AsyncCacheLoader
is constructed with an instance of the actual cache loader to be used. The AsyncCacheLoader
then delegates all requests to the underlying cache loader, using a separate thread if necessary. See the Javadocs on AsyncCacheLoader
for more details. If unspecified, the async
element defaults to false
.
Note
There is always the possibility of dirty reads since all writes are performed asynchronously, and it is thus impossible to guarantee when (and even if) a write succeeds. This needs to be kept in mind when setting the
async
element to true.
ignoreModifications
determines whether write methods are pushed down to the specific cache loader. Situations may arise where transient application data should only reside in a file based cache loader on the same server as the in-memory cache, for example, with a further shared JDBCCacheLoader
used by all servers in the network. This feature allows you to write to the 'local' file cache loader but not the shared JDBCCacheLoader
. This property defaults to false
, so writes are propagated to all cache loaders configured.
purgeOnStatup
empties the specified cache loader (if ignoreModifications
is false
) when the cache loader starts up.
shared
indicates that the cache loader is shared among different cache instances, for example where all instances in a cluster use the same JDBC settings t talk to the same remote, shared database. Setting this to true
prevents repeated and unnecessary writes of the same data to the cache loader by different cache instances. Default value is false
.
9.2.1. Singleton Store Configuration
<loaders passivation="false" shared="true"> <preload> <node fqn="/a/b/c"/> <node fqn="/f/r/s"/> </preload> <!-- we can now have multiple cache loaders, which get chained --> <loader class="org.jboss.cache.loader.JDBCCacheLoader" async="false" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false"> <properties> cache.jdbc.datasource=java:/DefaultDS </properties> <singletonStore enabled="true" class="org.jboss.cache.loader.SingletonStoreCacheLoader"> <properties> pushStateWhenCoordinator=true pushStateWhenCoordinatorTimeout=20000 </properties> </singletonStore> </loader> </loaders>
singletonStore
element enables modifications to be stored by only one node in the cluster, the coordinator. Essentially, whenever any data comes in to some node it is always replicated so as to keep the caches' in-memory states in sync; the coordinator, though, has the sole responsibility of pushing that state to disk. This functionality can be activated setting the enabled
subelement to true in all nodes, but again only the coordinator of the cluster will store the modifications in the underlying cache loader as defined in loader
element. You cannot define a cache loader as shared
and with singletonStore
enabled at the same time. Default value for enabled
is false
.
Optionally, within the
singletonStore
element, you can define a class
element that specifies the implementation class that provides the singleton store functionality. This class must extend org.jboss.cache.loader.AbstractDelegatingCacheLoader
, and if absent, it defaults to org.jboss.cache.loader.SingletonStoreCacheLoader
.
The
properties
subelement defines properties that allow changing the behavior of the class providing the singleton store functionality. By default, pushStateWhenCoordinator
and pushStateWhenCoordinatorTimeout
properties have been defined, but more could be added as required by the user-defined class providing singleton store functionality.
pushStateWhenCoordinator
allows the in-memory state to be pushed to the cache store when a node becomes the coordinator, as a result of the new election of coordinator due to a cluster topology change. This can be very useful in situations where the coordinator crashes and there's a gap in time until the new coordinator is elected. During this time, if this property was set to false
and the cache was updated, these changes would never be persisted. Setting this property to true
would ensure that any changes during this process also get stored in the cache loader. You would also want to set this property to true
if each node's cache loader is configured with a different location. Default value is true
.
pushStateWhenCoordinatorTimeout
is only relevant if pushStateWhenCoordinator
is true
in which case, sets the maximum number of milliseconds that the process of pushing the in-memory state to the underlying cache loader should take, reporting a PushStateException
if exceeded. Default value is 20000.
Note
Setting up a cache loader as a singleton and using cache passivation (via evictions) can lead to undesired effects. If a node is to be passivated as a result of an eviction, while the cluster is in the process of electing a new coordinator, the data will be lost. This is because no coordinator is active at that time and therefore, none of the nodes in the cluster will store the passivated node. A new coordinator is elected in the cluster when either, the coordinator leaves the cluster, the coordinator crashes or stops responding.