Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Introduction to Java Caching System

Learn more about Java Caching System (JCS) framework with descriptions and working examples.


advertisement

In modern application development, caching is one of the most important aspects to be considered during application design. The most common purpose of caching is to improve performance. A cache can be defined as a collection of objects. It contains stateful objects with keys as unique identifiers. The most common storage for any caching system is in memory. But caching systems can also store items in a disk, database or any other persistent storage. Java Caching System (JCS) is a distributed caching framework developed in Java. It improves application performance by providing support to manage various dynamic cached data. JCS supports in memory and disk caches. The JCS framework is completely configurable through the properties file and provides lot of flexibility in cache management.

This article will discuss the JCS framework with working examples.

Introduction

In most of the web applications, data is retrieved from the database. The database operation is expensive and time consuming. Present-day web applications are data intensive and first response time is the basic criteria for success. If the web application is frequently accessing the database for each request then its performance will be slow. As a result, many web applications are following different design techniques for reducing latency times and scale up.



JCS is a composite distributed caching system that works on JDK 1.4 and higher versions. The performance of JCS is very impressive for low put and high read applications.

The following are some of the major features of Java Caching System:

  • Memory management
  • Thread pool control
  • Extensible framework
  • Configurable runtime parameters
  • Key based data retrieval
  • Distributed composite cache
  • Element event handling

JCS – The Composite Cache

The foundation of Java Caching System is based on composite cache. There are four types of caches available for each region. Any type of cache can be plugged into the JCS configuration to make it active. The following are the four different types of caches:

  • Memory Cache (LRU): This is the widely used basic caching mechanism. The memory cache is extremely fast. It uses Least Recently Used (LRU) algorithm to manage the objects stored in the memory. The LRU memory cache is based on its own LRU Map implementation. This Map implementation is much faster compared to LRUMap implementation or any other type of Map.
  • Disk Cache (Indexed): The disk cache is used to store data when the memory cache is full. When indexing is used with the disk cache, the performance is much faster. Queue based process is used to store data on the disk. The disk cache is completely configurable. A thread pool is used to manage the queue worker threads that also make the process faster.
  • JDBC Disk Cache: This is another type of disk cache which is reliable, fast and fully configurable. The basic storage is JDBC compatible database. Both the keys and values are stored in the database. The data is stored as a BLOB and the expired data elements are removed periodically. Thread pool can also be used to manage queue worker threads for faster processing.
  • TCP Lateral Cache: This is a mechanism to distribute cached data on multiple distributed servers. This is also a completely configurable caching system. It can also use the UDP discovery mechanism to add nodes without disturbing the entire system. The TCP Lateral Cache establishes connections with socket servers on other nodes and performs the storage management. One server is sufficient to manage multiple regions.
  • Remote Cache using RMI: This is another caching option provided by JCS. In this mechanism, each node is not required to connect with other nodes. The remote cache server can be used as a connection point and each node can connect with it. The remote cache server is used to hold a serialized version of your object. The remote server can be grouped with other servers to recover failover.

Dependency Configuration

In the following section we will discuss a simple application using JCS. Before moving into it, we must have the following dependencies in the CLASSPATH. Please download the executable jars and put them in the CLASSPATH to build the application.

  • jcs-1.3.jar
  • commons-logging.jar
  • commons-lang-2.4.jar
  • concurrent.jar

Working with JCS

In this section we will discuss different components of Java Caching System and the configuration details. We will explain each component with a working example.

The following is a simple Employee class holding employee details. The class should implement Serializable interface as its data will be persisted. It contains getter/setter methods for reading and writing data.

Listing 1: Showing Employee class

public class Employee implements java.io.Serializable{
	 private String name;
	 private String address;
	 private String empid; 
	public Employee(String name, String address, String empid) {
		    this.name = name;
		    this.address = address;
		    this.empid = empid;
    } 
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getEmpid() {
		return empid;
	}
	public void setEmpid(String empid) {
		this.empid = empid;
	}
}

The following is the main EmployeeManager class which imports JCS packages to use the framework APIs. It uses a cache region known as 'empCache' to put and get data into/from memory. The data is stored in the cache memory by using a key/value pair. The retrieval is based on the key associated with each value. The application is showing addition/retrieval and removal of objects stored in a cache.

Listing 2: Showing EmployeeManager class

import org.apache.jcs.JCS;
import org.apache.jcs.access.exception.CacheException;
public class EmployeeManager {	
	 private JCS cache; 
	 public EmployeeManager()
	  {
	    try
	    {
	      // Load the cache
	      cache = JCS.getInstance( "empCache" );
	      // Initialize the cache, Here data can be loaded during initialization
	      cache.put( "123", new Employee( "Nick", "Detroit.USA", "123" ) );
	      cache.put( "143", new Employee( "Ric",  "Seattle.USA", "143" ) );
	      cache.put( "153", new Employee( "Jhon", "Chicago.USA", "153" ) );
	      cache.put( "163", new Employee( "Dan", "Houston.USA", "163" ) ); 
	    }
	    catch( CacheException e )
	    {
	      e.printStackTrace();
	    }
	  }
	 public void addEmployee( Employee emp )
	  {
	    try
	    {
	      cache.put( emp.getEmpid(), emp );
	    }
	    catch( CacheException e )
	    {
	      e.printStackTrace();
	    }
	  }
	  public Employee getEmployee( String empid )
	  {
	    return ( Employee )cache.get( empid );
	  }
	  public void removeEmployee( String empid )
	  {
	    try
	    {
	      cache.remove( empid );
	    }
	    catch( CacheException e )
	    {
	      e.printStackTrace();
	    }
	  }	  
	  public static void main( String[] args )
	  {
	    // Create the employee manager
	    EmployeeManager empManager = new EmployeeManager();
	    // Add employees to the employee manager
	    /*empManager.addEmployee(new Employee("Name1", "address1", "empid1"));
	    empManager.addEmployee(new Employee("Name2", "address2", "empid2"));
	    empManager.addEmployee(new Employee("Name3", "address3", "empid3"));*/
	    // Get employee
	    Employee emp = empManager.getEmployee("123");
	    System.out.println( "Employee details retrieved from cache: " + emp.getName()+"-"+emp.getAddress());
	    // Remove employee
	    empManager.removeEmployee("123");
	    // After removal of employee
	    System.out.println( "Employee details after removal from cache: " + empManager.getEmployee("123") );
	  }
}

The following is the configuration file cache.ccf. It holds all the configurable parameters with their values. The first section is the default cache region which holds the default values. If no custom region is configured then these default values will be used. The second section is defining the custom cache region which is empCache here. It defines the custom parameter values. The last section is the AUXILIARY CACHE region that describes the disk cache and other related parameters.

Listing 3: Showing configuration file

# DEFAULT CACHE REGION
jcs.default=DC
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.default.cacheattributes.UseMemoryShrinker=false
jcs.default.cacheattributes.MaxMemoryIdleTimeSeconds=3600
jcs.default.cacheattributes.ShrinkerIntervalSeconds=60
jcs.default.elementattributes=org.apache.jcs.engine.ElementAttributes
jcs.default.elementattributes.IsEternal=false
jcs.default.elementattributes.MaxLifeSeconds=21600
jcs.default.elementattributes.IdleTime=1800
jcs.default.elementattributes.IsSpool=true
jcs.default.elementattributes.IsRemote=true
jcs.default.elementattributes.IsLateral=true
# PRE-DEFINED CACHE REGIONS
jcs.region.empCache=DC
jcs.region.empCache.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.region.empCache.cacheattributes.MaxObjects=1000
jcs.region.empCache.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.region.empCache.cacheattributes.UseMemoryShrinker=false
jcs.region.empCache.cacheattributes.MaxMemoryIdleTimeSeconds=3600
jcs.region.empCache.cacheattributes.ShrinkerIntervalSeconds=60
jcs.region.empCache.cacheattributes.MaxSpoolPerRun=500
jcs.region.empCache.elementattributes=org.apache.jcs.engine.ElementAttributes
jcs.region.empCache.elementattributes.IsEternal=false
# AVAILABLE AUXILIARY CACHES
jcs.auxiliary.DC=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory
jcs.auxiliary.DC.attributes=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
jcs.auxiliary.DC.attributes.DiskPath=c:/temp
jcs.auxiliary.DC.attributes.MaxPurgatorySize=10000000
jcs.auxiliary.DC.attributes.MaxKeySize=1000000
jcs.auxiliary.DC.attributes.MaxRecycleBinSize=5000
jcs.auxiliary.DC.attributes.OptimizeAtRemoveCount=300000
jcs.auxiliary.DC.attributes.ShutdownSpoolTimeLimit=60

Conclusion

In this article we have discussed caching concepts and one of the most popular caching frameworks, known as Java Caching System. The article also covered different components of JCS and their implementation. Finally, we have discussed a working example based on Java Caching System framework. The JCS is very powerful and written in Java. The storage mechanism and its internal design are very powerful for high read and low put applications. The implementation is completely configurable so it can be integrated with any new and existing application without a great deal of effort.

 

About the Author

Kaushik Pal is a technical architect with 15 years of experience in enterprise application and product development. He has expertise in web technologies, architecture/design, java/j2ee, Open source and big data technologies. You can find more of his work at www.techalpine.com and you can email him here.



   
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap