How to Boost Redis With Local Caching in Java
You may also like: Java-Distributed Caching in Redis
Local caching is one of the most useful tactics for improving the performance of databases such as Redis. Redis developers who want to do local caching in Java will find that Redis doesn’t support this functionality out of the box.
In this article, we’ll discuss how you can take advantage of local caching in Java and Redis with a third-party Redis Java client such as Redisson.
What Is Local Caching?
Caches are memory buffers that are used to store data in a convenient location so that future requests for that data will execute more quickly.
In local caching, the most frequently used data in a database is stored physically closer to the application that accesses it, in a repository known as the local cache. For example, if the application is running on a client that frequently accesses a database server, the local cache may be stored on the client’s own hard drive, eliminating network latency
By storing data closer in a local cache, you can dramatically speed up response times and reduce network traffic; however, local caching also needs to be handled with care, to ensure that the data stored in the local cache remains consistent with the data in the original database.
Local Caching in Redis With Java
Developers can easily implement local in-memory caches in Java, whether using built-in Java data structures such as HashMaps or using third-party Java libraries.
The problem comes when developers want to use these local caching features with Redis, which doesn’t automatically support the use of the Java programming language.
Fortunately, there’s an easy solution: developers can make use of third-party Java frameworks like Redisson in their Redis projects. Redisson is a Java client for Redis that offers dozens of distributed Java objects and services. This makes the Redis learning curve significantly easier for developers who are familiar with the standard Java classes and interfaces.
In the next few sections, we’ll discuss several ways that developers can use Redisson to implement Java local caching in Redis.
Local Caching in Redis and Java With Maps
Maps in Java represent mappings between key-value pairs; they are one of the easiest ways to implement local caching in Java.
The RLocalCachedMap interface in Redisson extends Java’s built-in ConcurrentMap interface to include support for local caching in Redis. This local cache enables applications to execute read operations up to 45 times faster than normal.
Users can configure the following RLocalCachedMap features:
- Maximum cache size.
- Time to live per cache entry.
- Maximum idle time per cache entry.
- Eviction policy for cache entries.
- Synchronization strategy for cache changes.
Below is an example of how to use RLocalCachedMap in Redisson:
RLocalCachedMap<String, Integer> map = redisson.getLocalCachedMap("test", LocalCachedMapOptions.defaults());
String prevObject = map.put("123", 1);
String currentObject = map.putIfAbsent("323", 2);
String obj = map.remove("123");
// use fast* methods when previous value is not required
map.fastPut("a", 1);
map.fastPutIfAbsent("d", 32);
map.fastRemove("b");
RFuture<String> putAsyncFuture = map.putAsync("321");
RFuture<Void> fastPutAsyncFuture = map.fastPutAsync("321");
map.fastPutAsync("321", new SomeObject());
map.fastRemoveAsync("321");
If the RLocalCachedMap is no longer in use, it’s recommended to explicitly destroy the map; however, this is not strictly necessary if Redisson is shutting down:
RLocalCachedMap<String, Integer> map = ...
map.destroy();
Local Caching in Redis and Java With Spring Cache
Redisson also includes support for three third-party Java frameworks used for local caching: Spring Cache, Hibernate Cache, and JCache.
Spring is fully compatible with the Redisson framework, and Spring Cache is supported in Redisson via the RedissonSpringLocalCachedCacheManager class. Users can configure the following features:
- Maximum cache size.
- Time to live per cache entry.
- Maximum idle time per cache entry.
- Reconnection strategy.
- Synchronization strategy for cache changes.
Below is an example of how to configure Spring Cache in Redisson:
@Configuration
@ComponentScan
@EnableCaching
public static class Application {
@Bean(destroyMethod="shutdown")
RedissonClient redisson() throws IOException {
Config config = new Config();
config.useClusterServers()
.addNodeAddress("redis://127.0.0.1:7004", "redis://127.0.0.1:7001");
return Redisson.create(config);
}
@Bean
CacheManager cacheManager(RedissonClient redissonClient) {
Map<String, CacheConfig> config = new HashMap<String, CacheConfig>();
// define local cache settings for "testMap" cache.
// ttl = 48 minutes and maxIdleTime = 24 minutes for local cache entries
LocalCachedMapOptions options = LocalCachedMapOptions.defaults()
.evictionPolicy(EvictionPolicy.LFU)
.timeToLive(48, TimeUnit.MINUTES)
.maxIdle(24, TimeUnit.MINUTES);
.cacheSize(1000);
// create "testMap" Redis cache with ttl = 24 minutes and maxIdleTime = 12 minutes
config.put("testMap", new LocalCachedCacheConfig(24*60*1000, 12*60*1000, options));
return new RedissonSpringLocalCachedCacheManager(redissonClient, config);
}
}
Local Caching in Redis and Java With Hibernate Cache
Hibernate Cache is the second third-party Java local caching option in Redisson. Caching in Hibernate is accomplished in Redisson via the RedissonLocalCachedRegionFactory class. Users can configure the following features:
- Maximum cache size.
- Time to live per cache entry.
- Maximum idle time per cache entry.
- Eviction policy for cache entries.
- Reconnection strategy.
- Synchronization strategy for cache changes.
To learn more about implementing Hibernate Cache in Redis with Redisson, check out "Caching in Hibernate With Redis".
Local Caching in Redis and Java With JCache
Finally, you can also perform Java local caching in Redis with Redisson and JCache. Configuring the cache is done during JCache instance initialization through the LocalCacheConfiguration class. Users can configure the following features:
- Maximum cache size.
- Time to live per cache entry.
- Maximum idle time per cache entry.
- Eviction policy for cache entries.
- Reconnection strategy.
- Synchronization strategy for cache changes.
Below is an example of how to initialize a Java local cache with JCache and Redisson:
LocalCacheConfiguration<String, String> config = new LocalCacheConfiguration<>();
CacheManager manager = Caching.getCachingProvider().getCacheManager();
Cache<String, String> cache = manager.createCache("myCache", config);
// or
URI redissonConfigUri = getClass().getResource("redisson-jcache.yaml").toURI();
CacheManager manager = Caching.getCachingProvider().getCacheManager(redissonConfigUri, null);
Cache<String, String> cache = manager.createCache("myCache", config);
// or
Config redissonCfg = ...
Configuration<String, String> rConfig = RedissonConfiguration.fromConfig(redissonCfg, config);
CacheManager manager = Caching.getCachingProvider().getCacheManager();
Cache<String, String> cache = manager.createCache("namedCache", rConfig);
Conclusion
Redisson includes a variety of options for Java developers to perform local caching in Redis: Maps, Spring Cache, Hibernate Cache, and JCache.
Note that the last three options — Spring Cache, Hibernate Cache, and JCache — are only available for Redisson PRO users. Redisson PRO includes a variety of features and performance enhancements that set it apart from the open-source version of Redisson. These include data partitioning in cluster mode, XA transactions, ultra-fast speeds for multithreaded applications, and 24x7 support.
To learn more about the benefits of Redisson PRO, including local caching, get in touch with the Redisson team today.
Further Reading
Caching in Hibernate With Redis
Database Caching With Redis and Java
Using Read-Through and Write-Through in Distributed Cache