Aaron Schulz has uploaded a new change for review.
https://gerrit.wikimedia.org/r/230967
Change subject: More multi-DC tweaks to MessageCache::load()
......................................................................
More multi-DC tweaks to MessageCache::load()
* Use hash key volatility to propagate invalidations over DCs
in addition to memcached->APC instances.
* Make use of stale APC cache due to hash mismatch instead
of waiting around in some cases. This is similar to the
TTL expiry and volatility cases.
* Renamed $hashExpired and added some comments for clarity.
Change-Id: I8890fb174cae72c4ce8872df64f52f5cbd55183b
---
M includes/cache/MessageCache.php
1 file changed, 31 insertions(+), 24 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/67/230967/1
diff --git a/includes/cache/MessageCache.php b/includes/cache/MessageCache.php
index 8fe0bf9..304c4f2 100644
--- a/includes/cache/MessageCache.php
+++ b/includes/cache/MessageCache.php
@@ -260,29 +260,30 @@
# Loading code starts
$success = false; # Keep track of success
$staleCache = false; # a cache array with expired data, or
false if none has been loaded
- $hashExpired = false; # whether the cluster-local validation
hash is stale
$where = array(); # Debug info, delayed to avoid spamming debug
log too much
- # Local cache
- # Hash of the contents is stored in memcache, to detect if
local cache goes
- # out of date (e.g. due to replace() on some other server)
- if ( $wgUseLocalMessageCache ) {
- list( $hash, $hashExpired ) = $this->getValidationHash(
$code );
- if ( $hash ) {
- $cache = $this->getLocalCache( $code );
- if ( !$cache || !isset( $cache['HASH'] ) ||
$cache['HASH'] !== $hash ) {
- $where[] = 'local cache is empty or has
the wrong hash';
- } elseif ( $this->isCacheExpired( $cache ) ) {
- $where[] = 'local cache is expired';
- $staleCache = $cache;
- } elseif ( $hashExpired ) {
- $where[] = 'local cache validation key
is expired';
- $staleCache = $cache;
- } else {
- $where[] = 'got from local cache';
- $success = true;
- $this->mCache[$code] = $cache;
- }
+ # Hash of the contents is stored in memcache, to detect if
data-center cache
+ # or local cache goes out of date (e.g. due to replace() on
some other server)
+ list( $hash, $hashVolatile ) = $this->getValidationHash( $code
);
+
+ if ( $wgUseLocalMessageCache && $hash ) {
+ # Try the local cache and check against the cluster
hash key...
+ $cache = $this->getLocalCache( $code );
+ if ( !$cache ) {
+ $where[] = 'local cache is empty';
+ } elseif ( !isset( $cache['HASH'] ) || $cache['HASH']
!== $hash ) {
+ $where[] = 'local cache has the wrong hash';
+ $staleCache = $cache;
+ } elseif ( $this->isCacheExpired( $cache ) ) {
+ $where[] = 'local cache is expired';
+ $staleCache = $cache;
+ } elseif ( $hashVolatile ) {
+ $where[] = 'local cache validation key is
expired/volatile';
+ $staleCache = $cache;
+ } else {
+ $where[] = 'got from local cache';
+ $success = true;
+ $this->mCache[$code] = $cache;
}
}
@@ -292,7 +293,7 @@
# the lock can't be acquired, wait for the other thread
to finish
# and then try the global cache a second time.
for ( $failedAttempts = 0; $failedAttempts < 2;
$failedAttempts++ ) {
- if ( $hashExpired && $staleCache ) {
+ if ( $hashVolatile && $staleCache ) {
# Do not bother fetching the whole
cache blob to avoid I/O.
# Instead, just try to get the
non-blocking $statusKey lock
# below, and use the local stale value
if it was not acquired.
@@ -303,6 +304,12 @@
$where[] = 'global cache is
empty';
} elseif ( $this->isCacheExpired(
$cache ) ) {
$where[] = 'global cache is
expired';
+ $staleCache = $cache;
+ } elseif ( $hashVolatile ) {
+ # DB results are slave lag
prone until the holdoff TTL passes.
+ # By then, updates should be
reflected in loadFromDBWithLock().
+ # One thread renerates the
cache while others use old values.
+ $where[] = 'global cache is
expired/volatile';
$staleCache = $cache;
} else {
$where[] = 'got from global
cache';
@@ -319,8 +326,8 @@
# We need to call loadFromDB. Limit the
concurrency to one process.
# This prevents the site from going down when
the cache expires.
+ # Note that the slam-protection lock here is
non-blocking.
if ( $this->loadFromDBWithLock( $code, $where )
) {
- # Load from DB complete, no need to
retry
$success = true;
break;
} elseif ( $staleCache ) {
@@ -644,7 +651,7 @@
* Get the md5 used to validate the local disk cache
*
* @param string $code
- * @return array (hash or false, bool expiry status)
+ * @return array (hash or false, bool expiry/volatility status)
*/
protected function getValidationHash( $code ) {
$curTTL = null;
--
To view, visit https://gerrit.wikimedia.org/r/230967
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8890fb174cae72c4ce8872df64f52f5cbd55183b
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits