How to Prevent Cache Penetration, Concurrency, and Expiration Issues in Redis and Memcached
This article explains the three common cache problems—penetration, concurrency, and expiration—illustrates why they occur in high‑traffic systems, and provides practical techniques such as pre‑setting placeholder values, locking, and randomizing TTLs to keep databases healthy.
When using caches like Redis or Memcached, we usually encounter three common problems:
Cache penetration
Cache concurrency
Cache expiration
1. Cache Penetration
In many projects we first check the cache; if the key is missing we query the database and then store the result. If a particular key never exists in the cache, every request will hit the database, defeating the purpose of caching and potentially crashing the DB under heavy load.
A common mitigation is to pre‑set a placeholder value (e.g., "&&") for keys that are known to be absent. When the application reads this placeholder it knows the real data is missing and can decide whether to wait and retry later, thereby preventing unnecessary DB queries.
2. Cache Concurrency
When traffic spikes, a cache miss can cause many processes to query the database simultaneously and then try to write the same cache entry, putting excessive pressure on the DB and causing frequent cache updates.
One approach is to lock the cache lookup: if the key is missing, acquire a lock, fetch from the DB, populate the cache, and release the lock. Other processes wait for the lock to be released and then read the cached value, reducing duplicate DB hits.
3. Cache Expiration
If many cache entries share the same TTL, they may all expire at the same moment during a high‑concurrency period, causing a sudden surge of DB requests (a "cache avalanche").
A simple solution is to add a random offset (e.g., 1–5 minutes) to the base expiration time, spreading out expirations and lowering the chance of collective cache loss.
Summary
1. Cache penetration : querying data that never exists, which can be mitigated by storing a sentinel value for absent keys.
2. Cache concurrency : multiple processes querying the DB at the same time; use locking or sentinel values to serialize access.
3. Cache expiration : avoid synchronized expirations by adding random jitter to TTLs.
These techniques help keep the cache effective and protect the database from overload.
Q&A Highlights
Q1: How to keep DB and cache consistent?
A: After updating the DB, ensure the cache is refreshed; if the cache server is down, schedule an asynchronous task that retries until the cache becomes reachable.
Q2: How does the placeholder "&&" work for cache penetration?
A: The front‑end treats "&&" as a signal that the key is currently unavailable and either waits or aborts. Once the back‑end populates the real value, the placeholder is replaced.
Q3: What about using a secondary key as a lock?
A: A dual‑key scheme can act as a lock, but it introduces extra data and complexity.
Q4: What is multi‑level caching?
A: Combining an in‑process cache (e.g., Ehcache) with an external cache (e.g., Redis) forms a two‑level cache, improving resilience but still requiring careful consistency handling.
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.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
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.
