Redis Lazy Loading Cache with Guava Local Cache: Design, Implementation, and Evaluation
This article explains how to combine Redis lazy‑loading caching with Guava local cache in Java, presenting design diagrams, full code examples, and a discussion of the advantages, disadvantages, and suitable scenarios for this hybrid caching strategy.
In modern backend development, Redis is frequently used as a high‑performance cache to offload read traffic from relational databases, but heavy I/O can still become a bottleneck. Introducing a local cache such as Guava can reduce Redis read/write pressure while keeping the implementation simple.
Design Example – Redis Lazy Loading Cache
The proposed pattern stores data in MySQL without caching on creation; when a precise query occurs, the data is fetched from the database and then cached in Redis, achieving a "cache‑on‑read" behavior. A flow diagram illustrates the process.
// Pseudo‑code example – XxLazyCache
public class XxLazyCache {
@Autowired
private RedisTemplate
redisTemplate;
@Autowired
private XxService xxService;
/**
* Query: first check cache, then DB, finally populate cache.
*/
public Xx getXx(int id) {
Xx xxCache = getXxFromCache(id);
if (xxCache != null) {
return xxCache; // fast path
}
Xx xx = xxService.getXxById(id);
setXxFromCache(xx);
return xx;
}
/** Delete cache after update/delete */
public void deleteXxFromCache(long id) {
String key = "Xx:" + id;
redisTemplate.delete(key);
}
private void setXxFromCache(Xx xx) {
String key = "Xx:" + xx.getId();
redisTemplate.opsForValue().set(key, xx);
}
private Xx getXxFromCache(int id) {
String key = "Xx:" + id;
return redisTemplate.opsForValue().get(key);
}
}
// Service and entity classes omitted for brevityThe advantages of this approach are minimal cache size, low intrusion on CRUD operations, and plug‑in compatibility for legacy systems. The drawbacks include limited suitability for ever‑growing data sets and challenges in distributed micro‑service environments.
Redis Combined with Local Cache
In micro‑service scenarios where many services share a large Redis cache, a local Guava cache can further reduce latency and Redis load because it eliminates network round‑trips for hot keys.
Use case: assigning incremental IDs to devices in a high‑frequency streaming pipeline. The incremental counter is stored in Redis (using INCR ) and cached in a Redis hash; Guava caches the per‑device ID locally to avoid repeated hash lookups.
// DeviceIncCache – Guava + Redis hybrid cache
public class DeviceIncCache {
/** Local Guava cache */
private Cache
localCache = CacheBuilder.newBuilder()
.concurrencyLevel(16)
.initialCapacity(1000)
.maximumSize(10000)
.expireAfterAccess(1, TimeUnit.HOURS)
.build();
@Autowired
private RedisTemplate
redisTemplate;
private static final String DEVICE_INC_COUNT = "device_inc_count"; // Redis INCR key
private static final String DEVICE_INC_VALUE = "device_inc_value"; // Redis hash key
/** Get or generate incremental ID for a device */
public int getInc(String deviceCode) {
Integer inc = localCache.getIfPresent(deviceCode);
if (inc != null) {
return inc;
}
inc = (Integer) redisTemplate.opsForHash().get(DEVICE_INC_VALUE, deviceCode);
if (inc == null) {
inc = redisTemplate.opsForValue().increment(DEVICE_INC_COUNT).intValue();
redisTemplate.opsForHash().put(DEVICE_INC_VALUE, deviceCode, inc);
}
localCache.put(deviceCode, inc);
return inc;
}
}Advantages of this hybrid approach include persistent Redis data, ultra‑fast reads from Guava, controllable memory usage via expiration policies, and suitability for distributed deployments where each instance caches only its own subset of keys. Disadvantages are added implementation complexity and the fact that it only fits scenarios where cached data is append‑only (no updates).
Overall Summary
Local cache size is controllable and eviction policies are robust.
Ideal for precise‑query use cases and micro‑service architectures.
Not suitable when cached data changes frequently or when the total data volume is unbounded.
Provides significant performance gains by reducing Redis I/O.
By leveraging Redis’s rich data structures together with Guava’s flexible caching API, developers can achieve a balanced trade‑off between memory consumption and response latency in backend systems.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.