Plugin Directory

Opened 10 years ago

Closed 10 years ago

#2494 closed defect (fixed)

memcached: flush by rotating a key prefix

Reported by: andy's profile andy's profile andy Owned by: andy's profile andy's profile andy
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.

Attachments (3)

flush.diff (2.9 KB) - added by andy 10 years ago.
First patch
flush-2.diff (3.5 KB) - added by andy 10 years ago.
Also flush global groups when is_main_site().
flush-3.diff (3.9 KB) - added by andy 10 years ago.
Initialize flush number with microtime, not zero

Download all attachments as: .zip

Change History (4)

@andy
10 years ago

First patch

@andy
10 years ago

Also flush global groups when is_main_site().

@andy
10 years ago

Initialize flush number with microtime, not zero

#1 @andy
10 years ago

  • Resolution set to fixed
  • Status changed from new to closed

Released in 3.0.0 [1400627]

Note: See TracTickets for help on using tickets.