Caching in Java: Redis, Memcached, and Embedded Solutions for Pros

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Caching in Java: Redis, Memcached, and Embedded Solutions: Advanced Level



Caching is one of the key tools for improving the performance and scalability of Java applications. At an advanced level, a developer faces a choice between distributed systems (Redis, Memcached) and lightweight embedded caches (Caffeine, Guava). In this article, we will analyze architectural differences, use cases, and provide practical code examples for each solution.



1. Embedded Caches: Caffeine and Guava



Embedded caches run inside the JVM and do not require external services. They are ideal for storing temporary data that does not need to be synchronized between nodes.



Caffeine — Modern Standard

Caffeine is a high-performance caching library for Java that has replaced Guava Cache. It uses the Window TinyLFU algorithm for efficient record eviction.



// Maven dependency// <dependency>//     <groupId>com.github.ben-manes.caffeine</groupId>//     <artifactId>caffeine</artifactId>//     <version>3.1.8</version>// </dependency>

import com.github.benmanes.caffeine.cache.Cache;import com.github.benmanes.caffeine.cache.Caffeine;

import java.util.concurrent.TimeUnit;

public class CaffeineExample { public static void main(String[] args) { Cache<String, User> userCache = Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .maximumSize(10_000) .recordStats() .build();

// Write userCache.put("user:123", new User("Alice", "alice@example.com"));

// Read User user = userCache.getIfPresent("user:123"); System.out.println("Cached user: " + user);

// Atomic read with loading User result = userCache.get("user:456", key -> loadUserFromDB(key)); }

private static User loadUserFromDB(String key) { // Simulating loading from DB return new User("Bob", "bob@example.com"); }

static class User { private final String name; private final String email;

User(String name, String email) { this.name = name; this.email = email; }

@Override public String toString() { return "User{name='" + name + "', email='" + email + "'}"; } }}


Guava Cache — Proven Solution

Guava Cache from Google remains a popular choice for projects that already use the Guava library. It supports various eviction strategies and listeners.



import com.google.common.cache.CacheBuilder;import com.google.common.cache.CacheLoader;import com.google.common.cache.LoadingCache;

import java.util.concurrent.ExecutionException;import java.util.concurrent.TimeUnit;

public class GuavaCacheExample { public static void main(String[] args) throws ExecutionException { LoadingCache<String, String> cache = CacheBuilder.newBuilder() .expireAfterAccess(5, TimeUnit.MINUTES) .maximumSize(5000) .removalListener(notification -> System.out.println("Removed: " + notification.getKey())) .build(new CacheLoader<String, String>() { @Override public String load(String key) { return "Computed: " + key.toUpperCase(); } });

// Write cache.put("key1", "value1");

// Read with automatic loading String value = cache.get("key2"); System.out.println(value); // "Computed: KEY2" }}


2. Distributed Caching with Redis



Redis is a

Blogs

Book Recommendations