Why Redis Cache Expiration Triggers System Spikes
The article explains how massive simultaneous expiration of Redis keys can overload the single‑threaded server, causing brief request blocking, response‑time spikes, and even memory‑related issues in master‑slave setups.
In real‑world online projects, a large number of Redis keys expiring at the same time can cause brief blocking and response‑time spikes ("spikes"), prompting an analysis of the root causes.
Redis executes core commands on a single thread. If it tried to delete many expired keys immediately, the CPU would be consumed by callbacks and context switches, crashing the service. Therefore Redis uses a combination of lazy deletion and periodic deletion. Lazy deletion removes a key only when it is accessed; however, if an expired key is never accessed again, it remains in memory and can eventually cause memory overflow.
To address the lazy‑deletion limitation, Redis introduces a periodic deletion strategy that runs in the main thread. The execution flow of this periodic deletion is illustrated in the following diagram.
When the proportion of expired keys exceeds 25%, Redis starts a cleaning loop. It randomly samples 20 expired keys for deletion, and after every 16 iterations checks the elapsed time. If the cleaning takes more than 25 ms, the loop aborts and CPU time is returned to normal read/write requests.
Interface spike phenomenon
If many keys expire simultaneously, the expired‑key ratio surpasses the 25% threshold, triggering the cleaning loop. Because the main thread is occupied for up to 25 ms, client requests experience brief blocking and response‑time spikes, as shown in the diagram below.
"Ghost memory" in master‑slave architecture
In a replication setup, the slave never actively deletes data; it only removes keys when it receives a DEL command from the master. If the master is under heavy load or network latency delays the DEL propagation, the slave can accumulate many expired keys, eventually exhausting its memory and causing OOM.
In practice, write speed may exceed the cleaning speed, and deleting large keys can briefly block the main thread, leading to memory pressure. Redis mitigates this with eight eviction policies, grouped into three categories:
No eviction (noeviction): rejects new writes when memory is full.
Volatile‑* (expire‑only): evicts only keys with an expiration time (volatile‑lru, volatile‑lfu, volatile‑ttl, volatile‑random).
Allkeys‑* (all keys): evicts any key (allkeys‑lru, allkeys‑lfu, allkeys‑random).
Recommended settings for production: use allkeys-lru or allkeys-lfu for typical cache workloads to maximize hit rate, and volatile-lru for scenarios with critical persistent data that must be preserved.
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.
Lobster Programming
Sharing insights on technical analysis and exchange, making life better through technology.
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.
