Infinispan tutorial part 2

User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 

In the first tutorial we have covered some basic concepts about Infinispan, the revolutionary datagrid platform which has just reached 5.1.1 release. Now we will cover some advanced aspects related to cache stores, transactions, data eviction and clustering.

 Until now we have seen some basic examples of Infinispan's Local Cache. You might wonder if it makes sense to use Infinispan as Local Cache instead of a simple Hashtable or CuncurrentHashtable. Even if Infinispan focuses on large scale systems, it does make sense to use Infinispan also as Local cache.
For example:

  • Infinispan cache has eviction/expiry policies which are built-in. You don't have to worry about out-of-memory caused by collections growing too much.
  • Infinispan has the ability to store cache data on flat File or Jdbc, thus achieving data consistency in the event of system failure.
  • Infinispan can be configured to use and to participate in JTA compliant transactions.
  • Infinispan has MVCC-based concurrency. Thus it's highly optimized for fast, non-blocking readers.
  • You can monitor and manage Infinispan using JMX or Jopr plugin.

I think we mentioned enough reason why you can benefit of Infinispan even if you are not ready for a Clustered environment.Let's explore some of this great features:

Using Infinispan Cache Stores

Infinispan can be configured with one or several cache stores allowing it to store data in a persistent location such as shared JDBC database, a local filesystem and others. Using a Cache store requires to define a Cache with a loader element. For example the following define a cache which uses a Flat file Cache store:

<namedCache name="CacheStore">

     <loaders passivation="false" shared="false" preload="true">
          <loader class="org.infinispan.loaders.file.FileCacheStore" fetchPersistentState="true"
               ignoreModifications="false" purgeOnStartup="false">
            <properties>
                 <property name="location" value="C:\infinispan-4.0.0.FINAL\store"/>
               </properties>
          </loader>
     </loaders>
</namedCache>

This can be used to load the custom "CacheStore" configuration and persist one attribute:

CacheManager manager = new DefaultCacheManager("all.xml");   
Cache cache = manager.getCache("CacheStore");  
                
cache.put("key", "value");
        
cache.stop();
manager.stop();

This would produce a file, as soon as the CacheManager is stopped:
infinispan jboss tutorial clustering

By default Cache stores are configured to work synchronously. You can however configure updates to the cache as asynchronously written to the Cache store.
This means that updates to the cache store are done by a separate thread to the client thread interacting with the cache. You can achieve this by adding the async attribute to your loader:

<loader

          class="org.infinispan.loaders.file.FileCacheStore"
          fetchPersistentState="true" ignoreModifications="false"
          purgeOnStartup="false">
         . . . . . .        
        <async enabled="true" threadPoolSize="10"/>

</loader>

Using Transactions with InfiniSpan

Infinispan can be also configured to participate in JTA compliant transactions. All you need is including in your configuration file one of the TransactionManager classes that ship with Infinispan. For example the following is taken from the sample all.xml configuration:

<transaction
     transactionManagerLookupClass="org.infinispan.transaction.lookup.GenericTransactionManagerLookup"
     syncRollbackPhase="false"
     syncCommitPhase="false"
     useEagerLocking="false"/>
     

Implementing a JTA tx requires referencing the "Advanced Cache" from Cache instance as follows:

CacheManager manager = new DefaultCacheManager("all.xml");

Cache cache = manager.getCache();  
TransactionManager tm = cache.getAdvancedCache().getTransactionManager();
tm.begin();
cache.put("key", "value");
tm.commit();

Evicting Data from the Cache

Another reason why you should consider using Infinispan over a simple Hashtable caching is the ability to manage the amount of items in the cache using two simple strategies:

Expiration: data is removed from the cache when it reaches a lifespan or it's idle for too long
Eviction: data is removed from the cache when too many items are added to the cache.

This is a sample configuration which uses eviction:

<namedCache name="evictionCache">

  <eviction wakeUpInterval="500" maxEntries="5000" strategy="FIFO" />
  <expiration lifespan="60000" maxIdle="1000"/>
</namedCache>

Let's see a trivial example how the cache evicts data if the number of items exceeds maxEntries:

CacheManager cm = new DefaultCacheManager("all.xml");

Cache cache = cm.getCache("evictionCache");
        
for (int i=0;i<5000;i++) {
   cache.put("element"+i, "value"+i);    
}
System.out.println("First In Element is " + cache.get("element0"));
cache.put("element5000", "value5000");
System.out.println("Eviction Thread is waking up......");    
Thread.sleep(1000);
System.out.println("First In Element is " + cache.get("element0"));

This will result in:
First In Element is value0
Eviction Thread is waking up......
First In Element is null

Follow us on Twitter