Monday 2 December 2013

Ehcache Replication in Spring using JGroups

JGroups can be used as the underlying mechanism for the replication operations in ehcache. JGroups offers a very flexible protocol stack, reliable unicast and multicast message transmission.

On the down side JGroups can be complex to configure and some protocol stacks have dependencies on others.

To set up replicated caching using JGroups you need to configure a PeerProviderFactory of type JGroupsCacheManagerPeerProviderFactory which is done globally for a CacheManager

For each cache that will be replicated, you then need to add a cacheEventListenerFactory of type JGroupsCacheReplicatorFactory to propagate messages.


Configuration



There are two things to configure:


1. The JGroupsCacheManagerPeerProviderFactory which is done once per CacheManager and therefore once per ehcache.xml file.
2. The JGroupsCacheReplicatorFactory which is added to each cache's configuration.

The main configuration happens in the JGroupsCacheManagerPeerProviderFactory connect sub-property.

A connect property is passed directly to the JGroups channel and therefore all the protocol stacks and options available in JGroups can be set.

Suppose you have two servers in a cluster. You wish to replicated sampleCache1 and you wish to use UDP multicast as the underlying mechanism.The configuration for server1 and server2 are identical and will look like this:


<cacheManagerPeerProviderFactory

 class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"                                                properties="connect=UDP(mcast_addr=231.12.21.132;mcast_port=45566;):PINMERGE2:FD_S     OCK:VERIFY_SUSPECT:pbcast.NAKACK:UNICAST:pbcast.STABLE:FRAG:pbcast.GMS"



 propertySeparator="::"
/>


Configuring CacheReplicators



Each cache that will be replicated needs to set a cache event listener which then replicates messages to the other CacheManager peers. This is done by adding a cacheEventListenerFactory element to each cache's configuration. The properties are identical to the one used for RMI replication. The listener factory must be of typeJGroupsCacheReplicatorFactory.

For Server1 and Server2 : 

<cache name="employees" eternal="false" maxElementsInMemory="1000"
    overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0" 
    timeToLiveSeconds="500" memoryStoreEvictionPolicy="LRU" statistics="true">

    <cacheEventListenerFactory
     class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
     properties="replicateAsynchronously=true, replicatePuts=true,
     replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true" />

</cache>



Sample ehcache.xml:


<?xml version="1.0" encoding="UTF-8"?>

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"

updateCheck="true" monitoring="autodetect" dynamicConfig="true">
<cacheManagerPeerProviderFactory

 class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
           properties="connect=UDP(mcast_addr=231.12.21.132;mcast_port=45566;):PING:MERGE2:FD  _SOCK:VERIFY_SUSPECT:pbcast.NAKACK:UNICAST:pbcast.STABLE:FRAG:pbcast.GMS"          
 propertySeparator="::"

/>

<cacheManagerPeerListenerFactory
class="org.terracotta.ehcachedx.monitor.probe.ProbePeerListenerFactory"
properties="monitorAddress=10.35.34.193, monitorPort=9889,  memoryMeasurement=true" />

<cache name="employees" eternal="false" maxElementsInMemory="1000"
overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
timeToLiveSeconds="500" memoryStoreEvictionPolicy="LRU" statistics="true">

<cacheEventListenerFactory
class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
properties="replicateAsynchronously=true, replicatePuts=true,
  replicateUpdates=true, replicateUpdatesViaCopy=true,
                replicateRemovals=true" />
 </cache>

</ehcache>


Pom.xml Dependancy:

<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.6</version>
</dependency>

<dependency>
<groupId>org.jasig.ehcache</groupId>
<artifactId>ehcache-jgroups3replication</artifactId>
<version>1.7.4</version>
</dependency>


NOTE: 

Make sure that the firewall is turned off for the caching to work.

Only Serializable are suitable for replication.Some operations, such as remove, work off Element keys rather than the full Element itself. In this case the operation will be replicated provided the key is Serializable, even if the Element is not.

When configuring the CacheManagerPeerListener, note that if the value for <ipaddress of server> can be given as localhost only if all the servers are on the same machine. For servers on different machines in a network, this address should contain explicitly ip address of the machine on which the server is present.

You can refer to my previous blog -
Caching in a Spring Maven Project if you have just started learning caching


You can get the complete source code from here under the SpringHibernateProjectReplicationJGroups

No comments:

Post a Comment