Setting up ColdFusion 10 to replicate ehCache

Posted by Dan on Sep 24, 2014 @ 5:05 PM

Outside of Rob Brooks-Bilson's blog, there's not a lot of information on digging down into the ColdFusion's internal implementation of ehCache. I recently spent some time getting the built-in ehCache implementation to replicate across multiple nodes using RMI. Overall the process isn't that difficult, but due to the lack of information out there, it took me much longer to figure out the exact steps necessary to get things work.

NOTE: ColdFusion 10 added the ability to specify a specific ehcache.xml file on a Per Application basis using the this.cache.configfile value. Unfortunately, you can not use this method to configure replication. You will need to replace the default ehcache.xml that ships with ColdFusion.

  1. The first thing you want to do is backup your default ehcache.xml file.  This will be in your CF10's install folder at cfusion/lib/ehcache.xml. I recommend renaming the file ehcache.xml.bak. If you run into issues, you can always restore the original configuration.
  2. Open the ehcache.xml in your favorite editor.
  3. Find the CacheManagerPeerProvider comment. After that comment there's a sample <cacheManagerPeerProviderFactory /> element. Below that, insert the following element:

    <!--
      In order for this rule to work, you must:
    
      * Configure the operating system to use multicast
      * Open up UDP on port 4446 in the firewall
    -->
    <cacheManagerPeerProviderFactory
      class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
      properties="peerDiscovery=automatic,multicastGroupAddress=230.0.0.1,multicastGroupPort=4446,timeToLive=1"
      propertySeparator=","
    />

  4. Right below that, you should see the CacheManagerPeerListener comment. After the comment, there's a sample <CacheManagerPeerListener /> element. Below that, insert the following element:

    <!--
      In order for this rule to work, you must:
    
      * Open up TCP on port 40001 & 40002 in the firewall
    -->
    <cacheManagerPeerListenerFactory
      class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
      properties="port=40001,remoteObjectPort=40002"
    />

  5. Lastly, go down to the <defaultCache /> element and add the <cacheEventListenerFactory /> element. For example:

     <!--
     Mandatory Default Cache configuration. These settings will be applied to caches
     created programmtically using CacheManager.add(String cacheName).
    
     The defaultCache has an implicit name "default" which is a reserved cache name.
     -->
    <defaultCache
      maxElementsInMemory="10000"
      eternal="false"
      timeToIdleSeconds="86400"
      timeToLiveSeconds="86400"
      overflowToDisk="false"
      diskSpoolBufferSizeMB="30"
      maxElementsOnDisk="10000000"
      diskPersistent="false"
      diskExpiryThreadIntervalSeconds="3600"
      memoryStoreEvictionPolicy="LRU"
      clearOnFlush="true"
      statistics="true"
    >
      <!-- apply the replication listener to all caches created by ColdFusion -->
      <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
    </defaultCache>
  6. Save your changes.
  7. Restart ColdFusion.
  8. Open up the following firewall rules:
    • UDP: port 4446
    • TCP: ports 40001-40002

In order for this all to work, your server must be configured for multicast. In Redhat, this isn't a standard config, so there's some additional steps you may need to do.

While ehCache does allow you to set up a peer-to-peer configuration, it's very unwieldy and won't work well with ColdFusion, unless you explicitly use named regions in all your code.  The reason multicast is really required, is because it's the only method in which ehCache replication works without having to manually specify the name of each region to replicate.

I hope this helps someone out!

Categories: HTML/ColdFusion

4 Comments

  • Dan - what are you storing in the cache? Specifically, I'm curious what happens if you put a singleton like Coldspring in the cache. Can that be replicated? Or are you storing pretty much simple variables?

    I have seen warnings to not put something like Transfer in such a cache where objects have references to the service layer but it's not quite clear what will actually happen.
  • @Brian

    Our caching layer is pretty much caching results from complex operations, so it's generally not storing Objects. However, I did write a proxywrapper object which can automatically returns values from EhCache.

    So basically everything we're storing are native CF data types.
  • CFCs are native data types - but I presume you aren't including those? :)
  • @Brian,

    Yeah, I meant things like structs, queries, strings, etc.

Comments for this entry have been disabled.