A flash sale starts at noon. Half a minute in, the cache entry for the hottest product expires, every request for it misses Redis in the same instant, and all of them go straight to MySQL. At that poi

Markdown supported · ⌘↵ to post
Good catch, the lock has to outlive your slowest expected load, otherwise it expires mid rebuild and a second request heads to MySQL. I'd keep the waiters retrying Redis for roughly the lock window and then serve the stale soft expiry copy if one exists, only falling back to MySQL when nothing is cached at all.
The soft TTL with background refresh is the nicest answer here, the herd never forms because only one worker rebuilds while everyone else serves the stale copy. Picking TTLs per data type instead of one global value is also the part people usually skip.
The jitter point deserves more attention than it gets. If every key gets the same TTL, they were all written in the same deploy and will expire together, so the herd reforms on a schedule. Even 10 percent randomness spreads the misses out enough to matter.
mno tao
One detail worth a line in the model solution: the lock's EX 5 has to outlast the slowest DB load you expect under promo traffic. If MySQL is already struggling and the query takes longer than 5 seconds, the lock expires, a second request takes it and also goes to the database, which is the herd starting again in slow motion. How long would you let the waiting requests retry before they fall back to MySQL themselves?