JCS is a distributed caching system written in java. It is intended to speed up applications by providing a means to manage cached data of various dynamic natures.Like any caching system, JCS is most useful for high read, low put applications. Latency times drop sharply and bottlenecks move away from the database in an effectively cached system. The foundation of JCS is the Composite Cache, which is the pluggable controller for a cache region. Four types of caches can be plugged into the Composite Cache for any given region:
The Composite Cache orchestrates access to the various caches configured for use in a region. The JCS jar provides production ready implementations of each of the four types of caches. In addition to the core four, JCS also provides additional plugins of each type.
- LRU Memory Cache
- Indexed Disk Cache
- JDBC Disk Cache
- RMI Remote Cache
Getting Started
To start using JCS you need to
The purpose of the getting started guide is to help you get up and running with JCS as quickly as possible. In depth documentation on the various features of JCS is provided in the User's Guide.
STEP 1: Understand the Core Concepts
In order to use JCS, you must understand a few core concepts, most importantly you need to know the difference between "elements," "regions," and "auxiliaries". JCS is an object cache. You can put objects, or "elements," into JCS and reference them via a key, much like a hashtable.
You can think of JCS as a collection of hashtables that you reference by name. Each of these hashtables is called a "region," and each region can be configured independently of the others. For instance, I may have a region called Cities where I cache City objects that change infrequently. I may also define a region called Products where I cache product data that changes more frequently. I would configure the volatile Product region to expire elements more quickly than the City region.
"Auxiliaries" are optional plugins that a region can use. The core auxiliaries are the Indexed Disk Cache, the TCP Lateral Cache, and the Remote Cache Server. The Disk Cache, for example, allows you to swap items onto disk when a memory threshold is reached. You can read more about the available auxiliaries HERE.
STEP 2: Download JCS
Download the latest version of JCS. The latest JCS builds are located HERE.
If you would like to build JCS yourself, check it out from Subversion and build it as you would any other project built by Maven. The location of the repository is documented in the project info pages that are linked via the left nav.
STEP 3: Get the Required Dependencies
Beginning with version 2.0 the core of JCS (the LRU memory cache, the indexed disk cache, the TCP lateral, and the RMI remote server) requires only commons-logging; Beginning with version 1.2.7.0 and up to version 1.3, the core of JCS (the LRU memory cache, the indexed disk cache, the TCP lateral, and the RMI remote server) requires only two other jars.
STEP 4: Configure JCS
JCS is configured from a properties file called "cache.ccf". There are alternatives to using this file, but they are beyond the scope of the getting started guide.
The cache configuration has three parts: default, regions, and auxiliaries. You can think of the auxiliaries as log4j appenders and the regions as log4j categories. For each region (or category) you can specify and auxiliary (or appender to use). If you don't define a region in the cache.ccf, then the default settings are used. The difference between JCS and log4j is that in JCS, pre-defined regions do not inherent auxiliaries from the default region.
The following cache.ccf file (for v1.3) defines one region called "testCache1" and uses the Indexed Disk Cache, here called "DC" by default. The LRU Memory Cache is selected as the memory manager.
- # 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.testCache1=DC
- jcs.region.testCache1.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
- jcs.region.testCache1.cacheattributes.MaxObjects=1000
- jcs.region.testCache1.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache
- jcs.region.testCache1.cacheattributes.UseMemoryShrinker=false
- jcs.region.testCache1.cacheattributes.MaxMemoryIdleTimeSeconds=3600
- jcs.region.testCache1.cacheattributes.ShrinkerIntervalSeconds=60
- jcs.region.testCache1.cacheattributes.MaxSpoolPerRun=500
- jcs.region.testCache1.elementattributes=org.apache.jcs.engine.ElementAttributes
- # 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=jcs_swap
- 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
STEP 5: Programming to JCS
JCS provides a few convenient classes that should meet all your needs. To get a cache region you simply ask JCS for the region by name. If you wanted to use JCS for Cityobjects, you would do something like this:
- HelloWorld.java
- package demo;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.Serializable;
- import java.util.Properties;
- import java.util.Random;
- import java.util.logging.Logger;
- import org.apache.jcs.JCS;
- import org.apache.jcs.access.behavior.ICacheAccess;
- import org.apache.jcs.access.exception.CacheException;
- import org.apache.jcs.engine.control.CompositeCacheManager;
- public class HelloWorld {
- public static class City implements Serializable{
- public String name;
- public City(String n){this.name=n;}
- }
- public static Logger log = Logger.getLogger("HelloWorld");
- public static final String CacheRegionName = "city";
- public static ICacheAccess cache = null;
- /**
- * http://stackoverflow.com/questions/10733681/how-to-change-jcs-cache-ccf-files-path
- * @param args
- */
- public static void main(String[] args) throws Exception{
- try
- {
- CompositeCacheManager ccm = CompositeCacheManager.getUnconfiguredInstance();
- Properties props = new Properties();
- props.load(new FileInputStream(new File("cache.ccf")));
- ccm.configure(props);
- Random rdm = new Random();
- cache = JCS.getInstance( CacheRegionName );
- for(int i=0; i<100000; i++)
- {
- cache.put(i, new City("Taiwan-"+i)); // Store in Cache
- if(i!=0 && i%1000==0)
- {
- // Check City object in cache every 1000 rounds
- int id = rdm.nextInt(i);
- City city = (City)cache.get(id);
- System.out.printf("\t[Test] City with ID=%d=%s\n", id, city.name);
- }
- }
- System.out.printf("\t[Info] Done!\n");
- cache.remove();
- }
- catch ( CacheException e )
- {
- log.severe(String.format("Problem initializing cache for region name ["+ CacheRegionName + "]=%s", e));
- }
- }
- }
* Basic JCS Config
* Plugin overview
* Basic Web example