Redis Lazy Loading Cache and Guava Local Cache Design for High‑Frequency Data
This article explains how to combine Redis lazy‑loading caching with a Guava local cache to reduce Redis read/write pressure in high‑frequency data scenarios, provides Java code examples, discusses advantages and disadvantages, and offers practical guidance for backend developers.
Redis is frequently used as a cache to improve business performance, reduce pressure on relational databases such as MySQL, and even serve as a persistence layer for certain data, making it suitable for precise query and statistical workloads.
In high‑frequency data‑stream processing systems, the read/write pressure on Redis becomes a bottleneck; using a local cache like Guava can offload this pressure because it has no network I/O overhead.
Redis Lazy Loading Cache
Data is not cached when it is first inserted into MySQL; it is cached only during precise queries, achieving a "query‑then‑cache" behavior. This minimizes cache size while ensuring that only hot data occupies memory.
Flow diagram (illustrated in the original article) shows the lazy‑loading process.
// Pseudo‑code example Xx represents your business object such as User, Goods, etc.
public class XxLazyCache {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private XxService xxService; // your business service
/**
* Query: check cache first, if miss load from DB and set cache.
*/
public Xx getXx(int id) {
// 1. Check if data exists in cache
Xx xxCache = getXxFromCache(id);
if (xxCache != null) {
return xxCache; // cache hit
}
// 2. Load from DB (assume id always exists)
Xx xx = xxService.getXxById(id);
// 3. Set cache for next query
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 (Xx) redisTemplate.opsForValue().get(key);
}
}
// Business service example
public class XxService {
@Autowired
private XxLazyCache xxLazyCache;
public Xx getXxById(long id) {
// ... fetch from DB
return xx;
}
public void updateXx(Xx xx) {
// update DB
xxLazyCache.deleteXxFromCache(xx.getId()); // invalidate cache
}
public void deleteXx(long id) {
// delete from DB
xxLazyCache.deleteXxFromCache(id); // invalidate cache
}
}
// Entity class
@Data
public class Xx {
private Long id;
// ... other fields
}Advantages:
Ensures minimal cache size to satisfy precise‑query workloads, avoiding cold‑data memory waste.
Low intrusion on CRUD operations; cache is deleted synchronously.
Pluggable – old systems can be upgraded without pre‑initialising cache data.
Disadvantages:
Data volume must be controllable; not suitable for unbounded growth scenarios.
Not ideal for global caching in microservice architectures.
Redis Combined with Local Cache
In microservice environments, multiple services sharing a large Redis cache can cause high pressure; combining Redis with a Guava local cache reduces Redis load while providing ultra‑fast reads without connection overhead.
Flow diagram (illustrated in the original article) shows the interaction between Redis hash, local cache, and device‑increment generation.
/**
* This cache demonstrates how to combine Redis auto‑increment hash with a Guava local cache
* to generate, cache, and retrieve device increment numbers.
*/
public class DeviceIncCache {
private Cache<String, Integer> 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 auto‑increment key
private static final String DEVICE_INC_VALUE = "device_inc_value"; // Redis hash key
/** Get device increment number */
public int getInc(String deviceCode) {
// 1. Try local cache
Integer inc = localCache.getIfPresent(deviceCode);
if (inc != null) {
return inc;
}
// 2. Try Redis hash
inc = (Integer) redisTemplate.opsForHash().get(DEVICE_INC_VALUE, deviceCode);
// 3. If not exist, generate new increment in Redis
if (inc == null) {
inc = redisTemplate.opsForValue().increment(DEVICE_INC_COUNT).intValue();
redisTemplate.opsForHash().put(DEVICE_INC_VALUE, deviceCode, inc);
}
// 4. Populate local cache
localCache.put(deviceCode, inc);
return inc;
}
}Advantages:
Redis guarantees data persistence; local Guava cache provides ultra‑fast reads, reducing Redis pressure.
Guava offers rich APIs, expiration policies, and size limits, keeping memory usage under control.
Cache loss on service restart does not affect business correctness.
In distributed microservice scenarios each instance caches only its own device increments, optimizing memory usage.
The increment number also supports uniform partitioning for Kafka topic distribution.
Disadvantages:
Increases code complexity.
Only suitable for cache content that only grows (no updates).
Summary:
Local cache space is controllable with good expiration strategies.
Well‑suited for microservice and distributed environments.
Cache content must be immutable (append‑only).
Overall performance is high.
Redis provides a rich set of data types (increment/decrement, bitmap, hash, list, etc.) that are highly suitable for business system development, especially for counting, flagging, and queue‑style processing.
Guava local cache complements Redis by offering efficient in‑process reads and flexible eviction policies, helping developers balance space and time constraints.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Architects Alliance
Discussion and exchange on system, internet, large‑scale distributed, high‑availability, and high‑performance architectures, as well as big data, machine learning, AI, and architecture adjustments with internet technologies. Includes real‑world large‑scale architecture case studies. Open to architects who have ideas and enjoy sharing.
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.
