[wp-trac] [WordPress Trac] #31245: Replace alloptions with a key cache

WordPress Trac noreply at wordpress.org
Tue Oct 22 02:29:46 UTC 2019


#31245: Replace alloptions with a key cache
-------------------------------------+-----------------------------
 Reporter:  rmccue                   |       Owner:  SergeyBiryukov
     Type:  enhancement              |      Status:  reviewing
 Priority:  normal                   |   Milestone:  Future Release
Component:  Options, Meta APIs       |     Version:  2.1
 Severity:  normal                   |  Resolution:
 Keywords:  has-patch needs-testing  |     Focuses:  performance
-------------------------------------+-----------------------------

Comment (by dd32):

 I like the simple direction that [attachment:"31245.3.diff"] has gone in,
 but I have two main concerns: In a multi-database-server environment or
 where there's heavy load/lots of requests/second that this just swaps one
 cache race issue for another.

 This "solves" the cache race issue by having the next option get/page load
 pulling the data directly from the database, but in doing so introduces
 two cache race issues:
  1. In a heavy-option-write situation (Where the original cache race issue
 is most present) If an option write occurs in another page request between
 the time the DB Read and Cache set there's a "small" (Depending upon
 server speed/load) margin of time where the same race issue can occur.
  2. In a multi-database environment, #1 is more pronounced if the second
 thread setting the cache is reading from a secondary database where
 there's a likelyhood that the replication time isn't effectively instant.
 For example, take a site that's receiving 100 req/s: 1 thread updates an
 option, 99 threads immediately query their secondary database that's out
 of date by a millisecond and cache the old data.

 The second case above can be worked around by having alloptions queries
 being made against the primary DB server, although that might not be ideal
 for load purposes, but would an easy way to avoid it.

 The first case is arguably better than the current situation though, and
 ''might'' fix it for some sites.

 > I believe this is the best and most simple solution to this error. It is
 also how the meta api works

 Those cases are far more likely to happen with options than meta, as
 options often have a much heavier write load due to the ways that options
 have been used - In a way, that options/alloptions were never designed
 for.

 ----

 The benefit of shifting to multiple cache keys / multi_get() isn't maybe
 as obvious at first, but it works around the above in a fairly performant
 manner as a) race issues are not an issue (Multiple cache keys can update
 independently), b) there's no sudden DB load increase when clearing the
 cache (Not that this is much of an issue with modern servers) and c)avoids
 any per-key limits on the object cache (For example, the 1MB Memcache
 value limit that used to be hit on WordPress.com so often that I think it
 still has logic to split some cache values over multiple cache keys)

 Personally, I like how this issue has been fixed in existing Object
 caches, for example, [https://github.com/humanmade/memcache-object-
 cache/blob/master/object-cache.php#L140 Human Made's Memcache object-
 cache.php] has specific logic for internally converting the core
 alloptions cache to individual cache keys using it's get_multi
 implementation. It solves a lot of the problems that this ticket has, by
 just fixing the bug at the object-cache layer, so that core doesn't have
 to worry about how every different object cache differs.
 (I guess that's also another concern of mine - This change breaking an
 existing cache's implementation of alloptions -
 [attachment:"31245.3.diff"] won't break the above implementation, but
 it'll make it less performant)

 Perhaps an alternate options here is to specifically offload the
 alloptions caching to the object cache? Fix the Core API to do something
 like `if ( is_callable( $wp_object_cache, 'get_alloptions' ) ) { return
 $wp_object_cache->get_alloptions(); } else { /* existing code */ }`

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/31245#comment:81>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list