Cache Management using Ehcache

By Maurizio Farina | Posted on September 2017

In this tutorial we will show how to add Cache management to your Spring application. Spring abstracts the use of Cache so we can choose the provider. The tutorial uses the Ehcache framework.

In the second part of the tutorial it will be shown how to manage the persistence of the Cache in order to be used for clustered and distributed applications.

Cos'è la Cache?

The Cache is a system that stores resources (usually the output of a REST service, the execution of a database query, etc. ..) typically in memory so that when the same resource is requested, the system is able to recover and return the resource quickly.

Cache topics:

  • LRU cache
  • Eviction policy
  • Cache scenarios

LRU

LRU (least recently used) is one of cache system more common; when a client asks for a resource the LRU executes the following workflow::

  • if the resource is already present in the cache the system return the resource immediately
  • if the resource is not present in the cache it is retrieved and stored immediately in the cache
    • if the cache is full the resource less recently used is deleted and the new resource is added immediately

The cache system to allow searching for a resource as quickly as possible must use a hash encoding and a queue manager (queue, stack, sorted array, etc ..) to buffer resources.

Eviction policy

The cache uses the memory to allow a quick retrieval of resources so its consumption must be properly planned. Whenever a cache system is used, the removal strategy is also defined in order to avoid storing resources that are no longer needed.

Distributed cache

For distributed applications it is necessary to manage a distributed cache. This means that the cached resource may not be present on the local cache system. For this purpose, there are applications such as Memcached that use a cache mechanism that in its hash encoding associates the resource with the machine where the cache is stored.

Cache scenarios

The Ehcache framework allows to manae different use case scenarios.

Scenario Description
Local Cache The cache is managed locally by the application; Ehcache allows to choice which persistence policy to use.
Clustered Cache The cache is managed locally by the application but all local cache are aligned using Ehcache.
Distribuited Cache The cache is not managed locally by the application but by extgernal applications such as Redis, Memcached or MySql. The application is conneted to this external applications to read and write cache.

Depending on the use case used, it should be noted that an improper use of the cache can lead, paradoxically, to a slowing down of the application or even to a malfunction.

Common trouble

Cache eviction policy not defined. This could result in a noticeable increase in persistence used by Cache which could in some cases cause excessive memory usage or slow performance because cache recovery may be slower if we used a different resource.

Maven dependencies

1
2
3
4
5
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.7.4</version>
</dependency>

Spring Application Context Configuration

Before to proceed is better to add the following XSD to the locations declared in the Spring application context file:

http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd

Ehcache configuration in the application context file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<cache:annotation-driven />

<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
    <property name="cacheManager" ref="ehcache"/>
</bean>

<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    <property name="configLocation" value="classpath:ehcache.xml"/>
    <property name="shared" value="true"/>
</bean>

The above example enables the annotations related to the cache and declare EhCache as cache provider.

Ehcache configuration file is indicated by the configLocation property.

A small example of ehcache.xml to manage "UserSession" cache:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<ehcache
    xsi:noNamespaceSchemaLocation="ehcache.xsd"
    updateCheck="true"
    monitoring="autodetect"
    dynamicConfig="true"
    maxBytesLocalHeap="150M">

    <diskStore path="java.io.tmpdir" />

    <cache name="UserSession"
        maxEntriesLocalHeap="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        maxEntriesLocalDisk="10000000"
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">

        <persistence strategy="localTempSwap"/>
    </cache>

</ehcache>

diskStore and eternal

diskStore attribute set the cache as local and stored in the temporary folder. eternal setted to false allows to specify the eviction policy for each cache.

Cache a services result

Spring includes two Java annotations to declare the caches: @Cacheable and @CacheEvict respectively used to add and remove a resource from the cache.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.listfeeds.controllers;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/health")
public class HealthController {

    @RequestMapping("/live")
    public String live()  {
        return "UP";
    }

    @RequestMapping(value = "/info", method = RequestMethod.GET, produces="application/json")
    @Cacheable
    public String info()  {

        //retrieving services info could be require to query an external resource like a DB
        String infoService = "ListFeeds info REST services release 1.0.0";
        return infoService;
    }
}

Note

Spring manages the above class because it belongs to com.listfeeds.controllers package as indicated in the file rest-servlet.xml by the component-scan statement.

References