CacheManager Service in JBoss AS 5

Version 8

    Overview

    Many of the standard clustered services in JBoss Application Server use JBoss Cache (JBC) to maintain consistent state across the cluster.  Different services (e.g. web session clustering or second level caching of JPA/Hibernate entities) use different JBC instances, with each cache configured to meet the needs of the service that uses it. In AS 4, each of these caches was independently deployed in the deploy/ directory, which had a number of disadvantages:

     

    • Caches that end user applications didn't need were deployed anyway, with each creating an expensive JGroups channel. For example, even if there were no @Clustered EJB3 SFSBs, a cache to store them was started.
    • Caches are internal details of the services that use them. They shouldn't be first-class deployments.
    • Services would find their cache via JMX lookups. Using JMX for purposes other exposing management interfaces is just not the JBoss 5 way.

     

    In JBoss 5, the scattered cache deployments have been replaced with a new CacheManager service, deployed via the $JBOSS_HOME/server/all/deploy/cluster/jboss-cache-manager.sar. The CacheManager is a factory and registry for JBoss Cache instances. It is configured with a set of named JBoss Cache configurations. Services that need a cache ask the cache manager for the cache by name; the cache manager creates the cache (if not already created) and returns it.  The cache manager keeps a reference to each cache it has created, so all services that request the same cache name will share the same cache. When a service is done with the cache, it releases it to the cache manager.  The cache manager keeps track of how many services are using each cache, and will stop and destroy the cache when all services have released it.

     

    Standard Cache Configurations

     

    The following standard configuration ship with JBoss AS 5.0.0.GA. You can add others to suit your needs, or edit these configurations to adjust cache behavior. Additions or changes are done by editing the the deploy/cluster/jboss-cache-manager.sar/META-INF/jboss-cache-manager-jboss-beans.xml file. Note however that these configurations are specifically optimized for their intended use, and except as specifically noted below it is not advisable to change them.

     

    Config Name
    Usage
    standard-session-cacheStandard cache used for web sessions
    field-granularity-session-cacheStandard cache used for FIELD granularity web sessions
    sfsb-cacheStandard cache used for EJB3 SFSB caching
    ha-partitionUsed by ClusteredSingleSignOn, HA-JNDI, Distributed State
    mvcc-entityA config appropriate for JPA/Hibernate entity/collection caching that uses JBC's MVCC locking
    optimistic-entityA config appropriate for JPA/Hibernate entity/collection caching that uses JBC's optimistic locking
    pessimistic-entityA config appropriate for JPA/Hibernate entity/collection caching that uses JBC's pessimistic locking
    mvcc-entity-repeatableSame as "mvcc-entity" but uses JBC's REPEATABLE_READ isolation level instead of READ_COMMITTED [1]
    pessimistic-entity-repeatableSame as "pessimistic-entity" but uses JBC's REPEATABLE_READ isolation level instead of READ_COMMITTED [1]
    local-queryA config appropriate for JPA/Hibernate query result caching. Does not replicate query results. DO NOT store the timestamp data Hibernate uses to verify query result validity in this cache.
    replicated-queryA config appropriate for JPA/Hibernate query result caching. Replicates query results. DO NOT store the timestamp data Hibernate uses to verify query result validity in this cache.
    timestamps-cacheA config appropriate for the timestamp data cached as part of JPA/Hibernate query result caching.A clustered timestamp cache is required if query result caching is used, even if the query results themselves use a non-replicating cache like local-query
    mvcc-sharedA config appropriate for a cache that's shared for JPA/Hibernate entity, collection, query result  and timestamp caching. Not an advised configuration, since it requires cache mode REPL_SYNC, which is the least efficient mode. Also requires a full state transfer at startup, which can be expensive. Maintained for backwards compatibility reasons, as a shared cache was the only option in JBoss 4. Uses JBC's MVCC locking.
    optimistic-sharedA config appropriate for a cache that's shared for JPA/Hibernate entity, collection, query result  and timestamp caching. Not an advised configuration, since it requires cache mode REPL_SYNC, which is the least efficient mode. Also requires a full state transfer at startup, which can be expensive. Maintained for backwards compatibility reasons, as a shared cache was the only option in JBoss 4. Uses JBC's optimistic locking.
    pessimistic-sharedA config appropriate for a cache that's shared for JPA/Hibernate entity, collection, query result  and timestamp caching. Not an advised configuration, since it requires cache mode REPL_SYNC, which is the least efficient mode. Also requires a full state transfer at startup, which can be expensive. Maintained for backwards compatibility reasons, as a shared cache was the only option in JBoss 4. Uses JBC's pessimistic locking.
    mvcc-shared-repeatableSame as "mvcc-shared" but uses JBC's REPEATABLE_READ isolation level instead of READ_COMMITTED [1]
    pessimistic-shared-repeatableSame as "pessimistic-shared" but uses JBC's REPEATABLE_READ isolation level instead of READ_COMMITTED [1]

     

    Aliases

    The CacheManager also supports aliasing of caches; i.e. allowing caches registered under one name to be looked up under a different name. Aliasing is useful for sharing caches between services whose configuration may specify different cache config names. It's also useful for supporting legacy EJB3 application configurations ported over from AS 4.

     

    Aliases can be configured by editing the "CacheManager" bean in the jboss-cache-manager-jboss-beans.xml file. The following redacted config shows the standard aliases in AS 5.0.0.GA:

     

       <bean name="CacheManager" class="org.jboss.ha.cachemanager.CacheManager">
    
          . . .
     
          <!-- Aliases for cache names. Allows caches to be shared across 
               services that may expect different cache config names. -->
          <property name="configAliases">
             <map keyClass="java.lang.String" valueClass="java.lang.String">
                <!-- Use the HAPartition cache for ClusteredSSO caching -->
                <entry>
                   <key>clustered-sso</key>
                   <value>ha-partition</value>
                </entry>
                <!-- Handle the legacy name for the EJB3 SFSB cache -->
                <entry>
                   <key>jboss.cache:service=EJB3SFSBClusteredCache</key>
                   <value>sfsb-cache</value>
                </entry>
                <!-- Handle the legacy name for the EJB3 Entity cache -->
                <entry>
                   <key>jboss.cache:service=EJB3EntityTreeCache</key>
                   <value>mvcc-shared</value>
                </entry>
             </map>
          </property>
          
          . . .
          
       </bean>
    

     

    Usage with HttpSession Clustering

     

    By default, the HttpSession manager used with a clustered webapp will use the standard-session-cache described above to cache web sessions.  The field-granularity-session-cache is used if the webapp is configured for replication-granularity FIELD.

     

    This default can be changed on a per webapp basis via the replication-config/cache-name element in the webapp's jboss-web.xml:

     

    <!DOCTYPE jboss-web PUBLIC
        "-//JBoss//DTD Web Application 5.0//EN"
        "http://www.jboss.org/j2ee/dtd/jboss-web_5_0.dtd">
    
    <jboss-web>   
       <replication-config>
          <cache-name>custom-websession-cache</cache-name>
       </replication-config>
    </jboss-web>
    
    

    So, unlike in JBoss 4, different web applications can use different caches.  If you have two web applications that have different caching configuration requirements (e.g. one needs synchronous replication aka REPL_SYNC and the other doesn't) you can create separate named cache configurations in the CacheManager configuration, and then specify the correct configuration in each webapp's jboss-web.xml.

     

    If you wish to change the default behavior of the standard-session-cache or the field-granularity-session-cache, edit the standard-session-cache or field-granularity-session-cache section of the deploy/cluster/jboss-cache-manager.sar/META-INF/jboss-cache-manager-jboss-beans.xml file.

     

    Whether you create a new config or edit the existing one, most attributes should not be changed.  The following are likely candidates for changing:

     

    Config Element
    Notes
    <property name="cacheMode">REPL_ASYNC</property>Use REPL_SYNC if you need synchronous replication
    <property name="enabled">false</property> (in the buddy replication section)Set to true to enable buddy replication
    <property name="numBuddies">1</property>Used with buddy replication; specifies the number of backup nodes to whom a copy of the session should be replicated
    <property name="buddyPoolName">default</property>A way to specify a preferred replication group when buddy replication is enabled.  JBC tries to pick a buddy who shares the same pool name (falling back to other buddies if not available)
    <property name="multiplexerStack">udp</property>Name of the JGroups protocol stack configuration to use. See "JGroups ChannelFactory and Shared Transport in JBoss AS" for details.
    <property name="clusterName">DefaultPartition-SessionCache</property>Identifying name JGroups will use for this cache's channel. Only change this if you create a new cache configuration, in which case this property should have a different value from all other cache configurations.


    Usage with EJB3 SFSB Clustering

     

    By default, the EJB container for a clustered EJB3 Stateful Session Bean will use the sfsb-cache described above to cache web sessions.  On a per-bean basis this can be changed using the name attribute on the @org.jboss.ejb3.annotation.CacheConfig annotation:

     

    @Stateful
    @Clustered
    @CacheConfig(name="custom-sfsb-cache")
    @Remote(StatefulRemote.class)
    public class StatefulBean implements StatefulRemote
    

    This can also be configured via XML:

     

    <?xml version="1.0"?>
    <jboss
            xmlns="http://www.jboss.com/xml/ns/javaee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee
                                http://www.jboss.org/j2ee/schema/jboss_5_0.xsd"
            version="3.0">
          <enterprise-beans>
             <session>
                <ejb-name>NonAnnotationStateful</ejb-name>
                <clustered>true</clustered>
                <cluster-config>
                   <cache-name>custom-sfsb-cache</cache-name>
                </cluster-config>
             </session> 
          </enterprise-beans>
       </jboss>
    

    As with web sessions, different beans can use different caches. If you have two bean types that have different caching configuration requirements (e.g. one needs synchronous replication aka REPL_SYNC and the other doesn't) you can create separate named cache configurations in the CacheManager configuration, and then specify the correct configuration in each bean's @CacheConfig annotation or in jboss.xml.

     

    If you wish to change the default behavior of the sfsb-cache, edit its section of the deploy/cluster/jboss-cache-manager.sar/META-INF/jboss-cache-manager-jboss-beans.xml file.

     

    Whether you create a new config or edit the existing one, most attributes should not be changed.  The following are likely candidates for changing:

     

    Config Element
    Notes
    <property name="cacheMode">REPL_ASYNC</property>Use REPL_SYNC if you need synchronous replication
    <property name="enabled">false</property> (in the buddy replication section)Set to true to enable buddy replication
    <property name="numBuddies">1</property>Used with buddy replication; specifies the number of backup nodes to whom a copy of the session should be replicated
    <property name="buddyPoolName">default</property>A way to specify a preferred replication group when buddy replication is enabled.  JBC tries to pick a buddy who shares the same pool name (falling back to other buddies if not available)
    <property name="multiplexerStack">udp</property>Name of the JGroups protocol stack configuration to use. See "JGroups ChannelFactory and Shared Transport in JBoss AS" for details.
    <property name="clusterName">DefaultPartition-SessionCache</property>Identifying name JGroups will use for this cache's channel. Only change this if you create a new cache configuration, in which case this property should have a different value from all other cache configurations.

     

     

    Usage with JPA and Hibernate Entity Clustering

     

    One of the areas where the CacheManager is most useful is with second level caching of JPA/Hibernate entities. In the JPA/Hibernate context, a second level cache refers to a cache whose contents are retained beyond the scope of a transaction.  If you use more than one JBoss AS instance to run your JPA/Hibernate application and you use second level caching, you must use a cluster-aware cache. JBoss AS (and standalone Hibernate) provides a cluster-aware second level cache based on JBoss Cache.

     

    The CacheManager is particularly useful for JPA/Hibernate caching because there are actually four distinct types of items that can be cached: entities, collections, query results and entity timestamps. The CacheManager makes it possible to relatively easily set up an optimal caching configuration; in AS 4 only a single cache could be used, forcing a sort of suboptimal lowest-common-denominator configuration.

     

    See "Clustered JPA/Hibernate Second Level Caching in JBoss AS 5" for details.

     

    Editing the CacheManager Configuration

     

    The CacheManager is configured via the deploy/cluster/jboss-cache-manager.sar/META-INF/jboss-cache-manager-jboss-beans.xml file. The element most likely to be edited is the "CacheConfigurationRegistry" bean, which maintains a registry of all the named JBC configurations the CacheManager knows about. Most edits to this file would involve adding a new JBC configuration or changing a property of an existing one.

     

    The following is a redacted version of the "CacheConfigurationRegistry" bean configuration:

     

    <bean name="CacheConfigurationRegistry" class="org.jboss.ha.cachemanager.DependencyInjectedConfigurationRegistry">
       
          <!-- If users wish to add configs using a more familiar JBC config format
               they can add them to a cache-configs.xml file specified by this property.
               However, use of the microcontainer format used below is recommended.
          <property name="configResource">META-INF/jboss-cache-configs.xml</property>      
          -->
          
          <!-- The configurations. A Map<String name, Configuration config> -->
          <property name="newConfigurations">
            <map keyClass="java.lang.String" valueClass="org.jboss.cache.config.Configuration">
       
       <!-- The standard configurations follow.  You can add your own and/or edit these. -->   
          
       <!-- Standard cache used for web sessions -->
       <entry><key>standard-session-cache</key>
       <value>      
          <bean name="StandardSessionCacheConfig" class="org.jboss.cache.config.Configuration">
             
             <!-- Provides batching functionality for caches that don't want to interact with regular JTA Transactions -->
             <property name="transactionManagerLookupClass">org.jboss.cache.transaction.BatchModeTransactionManagerLookup</property>
                   
             <!-- Name of cluster. Needs to be the same for all members -->
             <property name="clusterName">${jboss.partition.name:DefaultPartition}-SessionCache</property>
             <!-- Use a UDP (multicast) based stack. Need JGroups flow control (FC)
                  because we are using asynchronous replication. -->
             <property name="multiplexerStack">${jboss.default.jgroups.stack:udp}</property>
             <property name="fetchInMemoryState">true</property>
             
             <property name="nodeLockingScheme">PESSIMISTIC</property>
             <property name="isolationLevel">REPEATABLE_READ</property>
             <property name="cacheMode">REPL_ASYNC</property>
          
              .... more details of the standard-session-cache configuration
          </bean>      
       </value>
       </entry>
       
       <!-- Appropriate for web sessions with FIELD granularity -->
       <entry><key>field-granularity-session-cache</key>
       <value>      
          
          <bean name="FieldSessionCacheConfig" class="org.jboss.cache.config.Configuration">              
               .... details of the field-granularity-standard-session-cache configuration
          </bean>      
    
       </value>
    
       </entry>
    
       ... entry elements for the other configurations
    
      </map>
      </property>
    </bean>
    

     

    To add a new configuration, you would add an additional element inside the <map> element shown above:

     

    <entry><key>my-custom-cache</key>
       <value>          
          <bean name="MyCustomCacheConfig" class="org.jboss.cache.config.Configuration">              
              .... details of the my-custom-cache configuration
          </bean> 
       </value>
    </entry>
    

     

    The actual JBC configurations are specified using the JBoss Microcontainer's schema rather than one of the standard JBC config formats. When JBC parses one of its standard config formats, it creates a Java Bean of type org.jboss.cache.config.Configuration with a tree of child Java Beans for some of the more complex sub-configurations (i.e. cache loading, eviction, buddy replication). Rather than delegating this task of XML parsing/Java Bean creation to JBC, we let the AS's microcontainer do it directly. This has the advantage of making the microcontainer aware of the configuration beans, which in later AS 5.x releases will be helpful in allowing external management tools to manage the JBC configurations.  The configuration format should be fairly self-explanatory if you look at the starndard configurations the AS ships; they include all the major elements. The types and properties of the various java beans that make up a JBC configuration can be seen in the JBC javadocs.

     


     

    1.For JPA/Hibernate second level caching, REPEATABLE_READ is only useful if the application evicts/clears entities from the EntityManager/Hibernate Session and then expects to repeatably re-read them in the same transaction. Otherwise, the Session's internal cache provides a repeatable-read semantic.
    2.Query result caching (or for that matter entity caching) may not improve application performance. Be sure to benchmark your application with and without caching.