So you want Distributed, Scalable and Highly Available Cache?

Abstract

So you want Distributed, Scalable and Highly Available Cache? If yes, then this is the right place for you. The Terracotta Ehcache release has these features inbuilt. The Express Installation mode has simplified Terracotta integration in your application.

How this post is organized
First we shall start with simple standalone cache and then see how Terracotta can easily help us create a Distributed, Scalable and Highly Available cache, with a few minor configurations

What all do you need run the example?

  • Terracotta 3.2.0 - Download it from here

Sample Application
Lets design a sample application (a real simple one), which we shall use to demonstrate the features. Device Monitoring is a common requirement in OSS System, and caching the Device information reduces the Database hits. The essential components of our application are
- DevideInfo - A POJO that stores device information
- CacheHandler - Class that handles cache initialization and other ops

Lets see the CacheHandler class, which is the heart of our implementation

public class DeviceInfo  implements Serializable {

    String deviceId;

    String name;
    
    // .... other device information

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDeviceId() {
        return deviceId;
    }

    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }
}

The class is simple and contains information related to the device.

Let see our CacheHandler class

public class CacheHandler {

    public Cache deviceCache;

    public void initCache() {
        // Initialize the CacheManager
        CacheManager cacheManager = CacheManager.create();
        // Get the Cache to store device information
        deviceCache = cacheManager.getCache("deviceCache");
    }

    public void addToCache(DeviceInfo device) {
        Element el = new Element(device.getDeviceId(), device);
        deviceCache.put(el);
    }

    protected int getDeviceCacheSize() {
        return deviceCache.getSize();
    }

    public static void main(String[] args) {
        CacheHandler handler = new CacheHandler();
        handler.initCache();

        // Lets add 10 devices
        // just to keep life simple
        for(int i = 0; i < 10; i++) {
            DeviceInfo device = new DeviceInfo();
            device.setDeviceId("Device-"+i);
            handler.addToCache(device);
        }

        // Not recommended in production
        System.out.println("Cache Size = "+handler.getDeviceCacheSize());

    }
}

The class has two main functions
- initCache - The API initializes the cache
- addToCache - The API adds the device information to the device cache

Lets see our ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd"
             updateCheck="true" monitoring="autodetect">
    
   <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            diskSpoolBufferSizeMB="30"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            />

    <cache name="deviceCache"
           maxElementsInMemory="1000000"
           maxElementsOnDisk="1000"
           eternal="false"
           overflowToDisk="false"
           diskSpoolBufferSizeMB="20"
           timeToIdleSeconds="100"
           timeToLiveSeconds="100"
           memoryStoreEvictionPolicy="LFU">
     </cache>

</ehcache>

In the configuration we have defined a deviceCache, that we shall use to store device information.

Following is the list of jars you would need to run this app

  • ehcache-core-1.7.2.jar
  • slf4j-api-1.5.8.jar
  • slf4j-jdk14-1.5.8.jar

All these jars are available as part of Terracotta installation under /distributed-cache directory

You can run this example and see the same in action.

Making it Distributed....

Now lets assume that we want to make the Cache fault tolerant, survive JVM crashes, as well as have it available on different JVM's. It should be able to Scale as we add more JVM's to it and other stuff. With Terracotta, we can just do it in a few steps without changing the code. the magic lies with Express Installation mode, introduced in Terracotta version 3.2.0 and above

Lets see the 3 steps that we need to perform

1. Updates to the ehcache.xml
Add following element to ehcache.xml

<terracottaConfig url="localhost:9510" />

and for the deviceCache, we add <terracotta /> element

here is the updated ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd"
             updateCheck="true" monitoring="autodetect">

   <terracottaConfig url="localhost:9510" /> 
    
   <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            diskSpoolBufferSizeMB="30"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            />

    <cache name="deviceCache"
           maxElementsInMemory="1000000"
           maxElementsOnDisk="1000"
           eternal="false"
           timeToIdleSeconds="100"
           timeToLiveSeconds="100"
           memoryStoreEvictionPolicy="LFU">

        <terracotta />
     </cache>

</ehcache>

There is no need to change the code 🙂

2. Add ehcache-terracotta-1.8.0.jar to the classpath

Lets start the Terracotta Server

3. Goto Terracotta_Install_dir/bin and execute

$ ./start-tc-server.sh

This shall start the Terracotta server

Now run the application on multiple JVM's. The device information is available on all client JVM's 🙂

To monitor Cache, you can use Terracotta Dev Console

If you have further question/queries, please visit Terracotta Forums.

What's coming up Next?
The next post shall touch on write-behind feature in the latest Terracotta Darwin release. Its essentially to get best of both worlds - Caching and Database Offloading 🙂 Stay tuned..

One thought on “So you want Distributed, Scalable and Highly Available Cache?

  1. Hi,

    Its a very good post..
    I have the same requirement, but not very much sure how to start on it.

    In my scenario, i want to place the cache in 2 servers on the same network(for high availability) and the both the servers should be in sync.

    Can you please explain this case.

    Thanks,
    -Venkat

Leave a Reply

Your email address will not be published. Required fields are marked *