Opened 10 years ago
Closed 10 years ago
#2494 closed defect (fixed)
memcached: flush by rotating a key prefix
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Priority: | high | Severity: | normal |
| Plugin: | not-listed | Keywords: | |
| Cc: | markjaquith, ryan |
Description
Core uses wp_cache_flush() in two places: wp_install() and update_core(). For these to work correctly, flush must work reliably and synchronously.
In memcached, flush works by invalidating every key in the memcached server. This is fine in simple setups but it can be hazardous and even unusable for larger deployments. In multi-site situations, one site's flush invalidates all sites' caches; this can cause a stampede on the database every time a site is upgraded. With twemproxy, the flush command isn't supported at all.
Another way to flush a cache is to change all of its keys simultaneously. This is how the attached patch works.
We change keys transparently by rotating a key prefix used by the client. This can be as simple as a number we increment for every flush. Handily, memcached comes with an incr() method. This flush number is prefixed to all cache keys except the one that stores the flush number itself. When flush() is called, a new prefix is generated and used for subsequent cache commands.
Each site gets its own flush number. This isolates flushes to single sites.
Because the flush number is also held in the local cache, a script that starts when the flush number is X will continue to use X until it increments or re-reads the number from memcached. Long-running scripts anticipating flushes by other processes can trigger a re-read by unsetting the flush_number in question.
For global cache groups we can either rotate a global prefix on every single site flush or we don't flush them at all. There's no wp_cache_flush_global_groups() function so we have to make that decision up front. The patch does not flush global groups. Whether this needs to change is up for discussion.
First patch