1 Reply Latest reply on Jun 16, 2009 7:52 AM by galder.zamarreno

    distributed entity cache (invalidation based)

      I am trying to deploy distributed caching for a single entity. I am running JBoss AS 5.1.0 with jdk 1.5. I have two nodes running on two separate servers in a single partition.

      I see the caching work fine on each single node but the cache does not replicate/invalidate between the two nodes (I'd like to use invalidation).

      Test case:
      1. Ran a JUnit test that loaded the entity on node1 and node2 so it was in the cache on each node in the partition.
      2. Ran a JUnit test that changed the entity on node1.
      3. Ran a JUnit test that loaded the entity on node1 and node2.

      From looking at logging in both of the servers I can tell that node2 has the stale version (grabbed the entity from its cache instead of reloading it). I also have looked at the database log to verify that node2 did not try to load the entity when I requested it after it was changed by node1.

      I added this to my entity class:

      import org.hibernate.annotations.Cache;
      import org.hibernate.annotations.CacheConcurrencyStrategy;
      
      @Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)
      


      I added this to my persistence unit.
       <property name="hibernate.cache.use_second_level_cache" value="true"/>
       <property name="hibernate.cache.use_query_cache" value="true"/>
       <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory"/>
       <property name="hibernate.cache.region.jbc2.cachefactory" value="java:CacheManager"/>
       <property name="hibernate.cache.region.jbc2.cfg.entity" value="mvcc-entity"/>
      <!-- Removing this had no effect
       <property name="hibernate.cache.region.jbc2.cfg.query" value="timestamps-cache"/>
      -->
      


      Is there some other attribute that must be set in order to have a node notify the other nodes in the partition when a cached entity has changed? mvcc-entity has the property cacheMode set to INVALIDATION_SYNC. I figured that would do it. I also tried using pessimistic-entity but had no luck.

      The only change that I have made to jboss-cache-manager-jboss-beans.xml is to set the multiplexer property to ${jboss.default.jgroups.stack:tcp} (did not want to use udp). I did this for each cache entry in this file.

      For example,
       <!-- A config appropriate for entity/collection caching that uses MVCC locking -->
       <entry><key>mvcc-entity</key>
       <value>
       <bean name="MVCCEntityCache" class="org.jboss.cache.config.Configuration">
      
       <!-- Node locking scheme -->
       <property name="nodeLockingScheme">MVCC</property>
       <!-- READ_COMMITTED is as strong as necessary for most
       2nd Level Cache use cases. -->
       <property name="isolationLevel">READ_COMMITTED</property>
       <property name="useLockStriping">false</property>
      
       <!-- Mode of communication with peer caches.
       INVALIDATION_SYNC is highly recommended as the mode for use
       with entity and collection caches. -->
       <property name="cacheMode">INVALIDATION_SYNC</property>
      
       <!-- Name of cluster. Needs to be the same for all members -->
       <property name="clusterName">${jboss.partition.name:DefaultPartition}-mvcc-entity</property>
       <!-- Use a UDP (multicast) based stack. A udp-sync stack might be
       slightly better (no JGroups FC) but we stick with udp to
       help ensure this cache and others like timestamps-cache
       that require FC can use the same underlying JGroups resources.
       <property name="multiplexerStack">${jboss.default.jgroups.stack:udp}</property>
       -->
      
       <!-- Use TCP -->
       <property name="multiplexerStack">${jboss.default.jgroups.stack:tcp}</property>
      
       <!-- Whether or not to fetch state on joining a cluster. -->
       <property name="fetchInMemoryState">false</property>
      
       <!-- The max amount of time (in milliseconds) we wait until the
       state (ie. the contents of the cache) are retrieved from
       existing members at startup. Ignored if FetchInMemoryState=false. -->
       <property name="stateRetrievalTimeout">60000</property>
      
       <!-- Number of milliseconds to wait until all responses for a
       synchronous call have been received. -->
       <property name="syncReplTimeout">17500</property>
      
       <!-- Max number of milliseconds to wait for a lock acquisition -->
       <property name="lockAcquisitionTimeout">15000</property>
      
       <!-- Hibernate 2LC can replicate custom types, so we use marshalling -->
       <property name="useRegionBasedMarshalling">true</property>
       <!-- Must match the value of "useRegionBasedMarshalling" -->
       <property name="inactiveOnStartup">true</property>
      
       <!-- Disable asynchronous RPC marshalling/sending -->
       <property name="serializationExecutorPoolSize">0</property>
       <!-- We have no asynchronous notification listeners -->
       <property name="listenerAsyncPoolSize">0</property>
      
       <property name="evictionConfig">
       <bean class="org.jboss.cache.config.EvictionConfig">
       <property name="wakeupInterval">5000</property>
       <!-- Overall default -->
       <property name="defaultEvictionRegionConfig">
       <bean class="org.jboss.cache.config.EvictionRegionConfig">
       <property name="regionName">/</property>
       <property name="evictionAlgorithmConfig">
       <bean class="org.jboss.cache.eviction.LRUAlgorithmConfig">
       <!-- Evict LRU node once we have more than this number of nodes -->
       <property name="maxNodes">10000</property>
       <!-- And, evict any node that hasn't been accessed in this many seconds -->
       <property name="timeToLiveSeconds">1000</property>
       <!-- Don't evict a node that's been accessed within this many seconds.
       Set this to a value greater than your max expected transaction length. -->
       <property name="minTimeToLiveSeconds">120</property>
       </bean>
       </property>
       </bean>
       </property>
       <property name="evictionRegionConfigs">
       <list>
       <!-- Don't ever evict modification timestamps -->
       <bean class="org.jboss.cache.config.EvictionRegionConfig">
       <property name="regionName">/TS</property>
       <property name="evictionAlgorithmConfig">
       <bean class="org.jboss.cache.eviction.NullEvictionAlgorithmConfig"/>
       </property>
       </bean>
       </list>
       </property>
       </bean>
       </property>
       </bean>
       </value>
       </entry>
      


      Thanks.

        • 1. Re: distributed entity cache (invalidation based)
          galder.zamarreno

          tcp stack still uses MPING, multicast based member discovery, to find other members in the cluster, so maybe the cluster did not form correctly, which would explain why invalidation does not happen.

          Check for view messages for the MVCCEntityCache cache instance in the logs. See if the view messages contain the two members in the cluster