This article explores the fundamentals of Spring Data Redis. We will discover how straightforward it is to connect with Redis using Spring auto-configuration and learn how to write custom configurations and modify Spring Data Redis’ default settings.
1. Introduction to Redis
Redis is an open-source, in-memory data structure store used as a database, cache, and message broker. It is a key-value store, with keys and values as strings, lists, sets, hashes, or sorted sets.
Developers often use Redis as a cache in front of a persistent database, (such as MySQL) for frequently accessed data to reduce the load. Because Redis stores data in memory, it can respond to requests quickly. Redis also provides other advanced features such as Lua scripting, transactions, pub/sub messaging, and geospatial indexing.
2. Redis Setup
We recommend installing and running Redis on your machine to follow along with this article. One Redis instance suffices for basic testing; however, for advanced features like clustering or sentinel mode, two or three instances may be required.
Find more information about Linux and MacOS downloads here. Please note that Redis does not officially support Windows, but we can find a port of the server here.
- In development environment, we can also run Redis using Docker as an alternative option.
- In test environment, we can consider using Testcontainers.
3. Maven
There are two supported connectors available to connect Redis from a Spring Boot application:
To configure and connect using Lettuce, we need to include spring-boot-starter-data-redis dependency in the project’s pom.xml file. Lettuce Java Redis client, which is included by default in Spring Boot, thereby eliminating the need to add any additional dependencies.
For Jedis, we need to include one additional client’s library in dependencies.
For unit testing, include the latest version of testcontainers-redis-junit-jupiter which adds support for running Testcontainer for Redis server.
4. Spring Boot Configuration
Spring boot autoconfiguration configures the StringRedisTemplate and RedisTemplate instances that we can directly inject and use to perform operations on Redis database.
Once configured, RedisTemplate and StringRedisTemplate are thread-safe and can be reused across multiple instances.
4.1. Connection Properties
By default, autoconfiguration tried to connect to a Redis server at localhost:6379
. We can provide the custom connection details in the properties file.
There are a lot of other properties we can configure. The complete list of configuration properties is available in the Spring Boot documentation.
Using the above connection properties, Spring boot automatically creates an instance of RedisConnectionFactory. The RedisConnectionFactory provides the core building block for Redis communication, as it handles the communication with the Redis backend. It also automatically translates the underlying library exceptions to Spring DAO exceptions.
4.2. RedisTemplate
RedisTemplate provides a higher-level abstraction for interacting with Redis. While RedisConnection provides lower-level methods that handle binary values (byte arrays), the RedisTemplate handles serialization and connection management, relieving users from dealing with such details.
Then we customize a RedisTemplate using RedisConnectionFactory as follows:
The RedisTemplate supports various operations such as ValueOperations, HashOperations, ListOperations, SetOperations, GeoOperations, etc.
RedisTemplate utilizes a Java-based serializer for the majority of its operations, resulting in the serialization and deserialization of objects. It allows for the customization of the serialization mechanism, with various implementations offered by the Redis module, which are available in the org.springframework.data.redis.serializer package.
4.3. StringRedisTemplate
Redis modules offer two extensions to RedisConnection and RedisTemplate that are StringRedisConnection (with its DefaultStringRedisConnection implementation) and StringRedisTemplate. These extensions are specifically designed for handling String data commonly stored in Redis. Both the template and connection are bound to String keys and utilize the StringRedisSerializer, ensuring that the stored keys and values are human-readable. This makes them a convenient choice for efficient String operations.
4.4. Cache Operations
Data can be stored by using various data structures within Redis such as List, Map, binary or strings etc. These operations are represented with different interfaces:
- HashOperations
- ListOperations
- SetOperations
- ValueOperations
- GeoOperations, etc.
We can get the reference of these operations for direct access using the @Resource annotation:
In not using the interface references, we can use the opsFor[X]()
methods provided by RedisTemplate / StringRedisTemplate to persist and retrieve data from the Redis database. For example, in the following snippet, we are invoking the methods provided byValueOperations.
5. Custom Configuration
In the above configuration, we used Spring Boot connection default settings like connection pool, serializer, deserializer, etc. In the upcoming sections, we will see how we can modify these properties.
5.1. Connection Pool
Spring Data Redis uses commons-pool2 library to configure connection pooling. So, we need first to add the below dependency in our pom.xml file.
To configure the connection pool, the next step is to add connection pool-related properties as shown below:
Next, let’s configure the connection pool using org.apache.commons.pool2.impl.GenericObjectPoolConfig.
Next, configure the LettucePoolingClientConfiguration and LettuceConnectionFactory instances. The similar configuration can be done for the Jedis connector.
5.2. Redis Connections
To add custom connection details, we first add them in the properties file as shown below:
Then we inject the auto-configured RedisProperties bean and use it appropriately to initialize the connections.
5.2.1. Standalone Configuration
We can create a standalone connection using RedisStandaloneConfiguration class using the host and port defined in the properties file.
5.2.2. Sentinel Configuration
Redis Sentinel is a monitoring solution for Redis instances that handles automatic failover of Redis masters and service discovery. It not only allows data to be safely stored at more nodes. It also allows, by using Lettuce, to read data from replicas while pushing writes to the master. We can set the read/write strategy to be used by using LettuceClientConfiguration.
To start Redis in Sentinel mode, we use the docker-compose mentioned here.
If our Redis server is running in Sentinel mode, then the below configuration needs to be used:
With the help of RedisSentinelConfiguration class, we set up RedisConnection via LettuceConnectionFactory.
Then we create a LettuceClientConfiguration where we set a custom command timeout (default is 60 seconds) and preference for reading from slaves instead of master.
5.3. Custom Serializer/Deserializer
To create a custom serializer and deserializer for RedisTemplate, create a class that implements RedisSerializer<T> interface and overrides the byte[] serialize(Object o) and Object deserialize(byte[] bytes) method with custom logic. We have used Jackson’s ObjectMapper but you can use any library of your choice.
We can now use the above serializer in the RedisTemplate configuration to use our custom serializer instead of the Spring Data Redis default serialization as shown below.
5.4. Error Handling
By default, SimpleCacheErrorHandler is used by Spring Data Redis, and it simply throws the exception back to the client. However, in practice, failing to retrieve an object from the cache should not affect the primary functioning. Spring provides a CacheErrorHandler interface, a cache error handler strategy for you to handle those circumstances.
RedisCacheErrorHandler logs the error for further investigation instead of throwing back to the client. It provides 4 methods for handling different types of errors:
- handleCacheGetError()
- handleCachePutError()
- handleCacheEvictError()
- handleCacheClearError()
Below is a CacheErrorHandler implementation example that you can customize for further requirements.
Next, we implement the CachingConfigurer interface or extend from CachingConfigurerSupport class to register the custom CacheErrorHandler that we have created as shown below:
5.5. CacheManager
Next, we can configure the following beans to ease the development:
cacheManager – We initialize the cache Manager to the Redis connection created above and supply the configuration for the cache with the cache configuration bean. This helps with the @Cacheable annotation.
cacheConfiguration – The behavior of RedisCache created with RedisCacheManager is defined with RedisCacheConfiguration. The configuration lets you set key expiration times, prefixes, and RedisSerializer implementations for converting to and from the binary storage format.
6. Test
Finally, Let’s use the customRedisTemplate that we configured with our implementation of serializer and deserializer and perform different operations on the Redis Database.
Once we run the above tests, we can query the Redis DB and check that the keys are present.

7. Conclusion
In this article, we went through the basics of Spring Data Redis. We learned how to configure RedisTemplate with custom Serializer/Deserializer, CacheErrorHandler and CacheManager. We also went through some of the CRUD operations supported by Redis.
Happy Learning !!
Comments