Springboot Caching with Memcached and Redis

Eranda Rajapakshe
3 min readMay 19, 2019

--

Memcached is a popular distributed memory caching implementation often used in performance critical services. After the introduction in 2003 as an opensource project, Memcached was improved by and used by most of the modern day system. Eg: Facebook, Youtube, Twitter

Current Memcached server implementation is done using C and source code is maintained here[1] Often seen use case with Memcached is, cache database responses and reduce the time-consuming database calls. This is one of the tech talk done by Facebook CEO on how they have improved and integrated Memcached into Facebook. [2]

By today, Amazon AWS Elasticache supports Memcached as one of their caching options. [3] Users seamlessly integrate with Elasticache Memcached to make the caching more scalable.

Springboot caching supports several caching providers by default. [6] Since Memcached is not supported out of the box, we need to add it as a custom cache provider implementation. There are some third-party implementations [7] to serve this purpose, but using them might be complex. So it's better to do it by yourself if you have a good idea about the requirement. Following steps explains how to integrate Memcached caching into Springboot service to reduce the number of database calls.

To start, I have created a simple Springboot backend application with an API to expose data in a database. Please note that in this example, I will be using H2 in-memory database for the sake of simplicity.

  • This branch (no-cache) [4] contains a simple Springboot application, layered into web, service, and repository. Implementation in the branch will not contain any caching improvements, therefore each API call goes to the database.
  • In the next branch, (inbuilt-cache)[5] I have enabled Springboot default cache which uses an in-memory concurrent hashmap for caching. Note that I have only added @Cacheable("personCache") and @EnableCache annotations on top of the no-cache project to enable caching. If your API has POST/PUT methods and DELETE method you can make use of @CachePut and @CacheEvict annotations.
  • In the redis branch [8], I have converted inbuilt cache implementation to Redis based cache implementation. This conversion needed only following additions,

1. Adding dependency to the pom file

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2. Add configs to application.properties file

spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379

You need to run Redis server in background to test this. If you are using docker, you can use following commands to simply run a redis container on your machine.

docker pull redis
docker run --name redis-server -p 6379:6379 redis
  • In the memcached branch [9], you can see the changes I have added to enable to caching using Memcached client. Basically, I have used two classes one to interact with Memcached clients APIs (Memcached.java) and another one to load configurations and initialize Memcached implementation (MemcachedConfiguration.java). This will override the inbuilt caching implementation with the Memcached implementation.

Following is the Memcached client API invocation class. This will create the MemcachedClient which is coming from the Memcached library and invoke it matching with the Springboot Cache interface API.

This is the configuration class I have used to load the Memcached implementation as the caching provider. This will create a CacheManager bean to override the default cache implementation in Springboot. memcachedAddresses variable should be initialized with the Memcached server(s) address(es), for testing purposes you can run a local Memcached server or a cluster.

If you are using docker and you need to run a local Mecached node for testing you can use following commands,

docker pull memcached
docker run --name memcached-server -p 11211:11211 memcached

Note:

In this example, I have only discussed about caching calls going to the database. But depending on your system, we can use caching in other layers/ external calls as well. For example, let's say the service layer methods do CPU excessive work and return similar outputs to given inputs. Then Springboot caching can be applicable to those methods.

Also in this article, I didn’t go into deep configuration and implementation info on Springboot caching. For more details, you can refer to Springboot documentation on caching. [6]

References

[1]. https://github.com/memcached/memcached

[2]. https://www.youtube.com/watch?v=UH7wkvcf0ys

[3]. https://aws.amazon.com/elasticache/memcached/

[4]. https://github.com/erandacr/springboot-memcached/tree/no-cache

[5]. https://github.com/erandacr/springboot-memcached/tree/inbuilt-cache

[6]. https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-caching.html

[7]. https://github.com/sixhours-team/memcached-spring-boot

[8]. https://github.com/erandacr/springboot-memcached/tree/redis

[9]. https://github.com/erandacr/springboot-memcached/tree/memcached

[10]. https://thysmichels.com/2015/04/03/setup-spring-enablecaching-for-memcached/

[11]. http://memcached.org/

--

--