Thursday, December 18, 2008

Simple demo of clustering Ehcache

To cluster a cache between 2 or more JVM's, it's quite simple if you use Terracotta underneath. It will handle the networking, the shared memory, transparently for you. There's no extra API but a configuration file.

Terracotta also has maven plugin support so you could grab the demo project below and run without downloading anything.

The demo is only one Java source file. It is meant to be run in 2 VM's.

I used a cyclic barrier to synchronize between the 2 VM's. It will block until both VM hit the "await()" call. The first node will create a cache and populate it with 2 elements. The second node then queries out of the cache to demonstrate that it could get to the shared data.

package demo;

import java.util.concurrent.CyclicBarrier;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;

public class EhcacheDemo {

private CacheManager manager = CacheManager.create();
private CyclicBarrier barrier = new CyclicBarrier(2);

public void run() throws Exception {
Cache testCache;

System.out.println("Waiting for the other node...");
if (barrier.await() == 0) {
System.out.println("Creating the testCache...");
testCache = new Cache("test", 100, MemoryStoreEvictionPolicy.LFU, true,
null, false, 60, 30, false, 0, null);
manager.addCache(testCache);
}

barrier.await();
testCache = manager.getCache("test");

if (barrier.await() == 0) {
System.out.println("First node: adding 2 elements...");
testCache.put(new Element("k1", "v1"));
testCache.put(new Element("k2", "v2"));
} else {
System.out.println("Second node: querying 3 elements...");
System.out.println(testCache.get("k1"));
System.out.println(testCache.get("k2"));
System.out.println(testCache.get("k3"));
}

System.out.println("Done!");
}

public static void main(String[] args) throws Exception {
new EhcacheDemo().run();
}

}


Note that second node is also querying for non-existed element "k3" as a sanity check.

So how does Terracotta know what I want to share? From the above code, I tell Terracotta to share the cache "manager" and "barrier" by marking them as root in Terracotta configuration file tc-config.xml

<application>
<dso>
<instrumented-classes/>
<roots>
<root>
<field-name>demo.EhcacheDemo.manager</field-name>
</root>
<root>
<field-name>demo.EhcacheDemo.barrier</field-name>
</root>
</roots>
</dso>
</application>



After you download the project, just run this Maven commands:

mvn install
mvn tc:run


The output would be something like this:

[INFO] [node1] Waiting for the other node...
[INFO] [node0] Waiting for the other node...
[INFO] [node0] Creating the testCache...
[INFO] [node1] First node: adding 2 elements...
[INFO] [node0] Second node: querying 3 elements...
[INFO] [node1] Done!
[INFO] [node0] [ key = k1, value=v1, version=1, hitCount=2, CreationTime = 1229592169906, LastAccessTime = 1229592170081 ]
[INFO] [node0] [ key = k2, value=v2, version=1, hitCount=2, CreationTime = 1229592170070, LastAccessTime = 1229592170145 ]
[INFO] [node0] null
[INFO] [node0] Done!

3 comments:

Unknown said...

This is pretty awesome!

Is it really that simple to share objects with terracotta? This somehow replaces remoting, right? Stunning!

Unknown said...

Nick,

Thanks for stopping by. And yes, simplicity and transparency while still preserving Java memory model is what Terracotta aims for.

You could check out this blog http://unserializableone.blogspot.com/2006/10/share-precious-heap-memory-accross.html or try more demos in the kit.

Unknown said...

we are doing a project on service discovery using clusterin in wsn....need a start up code in java...could u help?.....