Objektcache
MediaWiki verwendet Caching in vielen Komponenten und auf vielen Ebenen. This page documents the various caches we use inside the MediaWiki PHP application.
Allgemein
There are two kinds of stores described in the context of object caches in MediaWiki:
- Cache. A place to store the result of a computation, or data fetched from an external source (for higher access speeds). This is a "cache" in the computer science definition.
- Stash. A place to store lightweight data not stored anywhere else. Also known as a stash (or "hoard" of objects). These are values that are not possible (or not allowed) to be recomputed on-demand.
Begriffe
A cache key is said to be "verifiable" if the program is able to verify that the value is not outdated.
This applies when a key can only have one possible value, such as computing the 100th digit of Pi, could be cached under the key math_pi_digit:100
.
The result can be safely stored in high-speed access stores without coordination, because it will never need to be updated or purged.
If it expires from the cache, it can be re-computed and produce the same result.
The same applies to storing the wikitext of a certain revision to a page.
Revision 123 has happened and will always contain the same content.
If the program knows the revision ID it is looking for, a cache key like revision_content:123
could also be a verifiable cache key.
Storing structured data
MediaWiki supports storing of both primitive values (bool, int, string) and (potentially nested) structures of arrays. It is also technically possible to store plain objects (stdClass) and instances of arbitrary classes, which relies on PHP serialization, but relying on this mechanism is deprecated for security reasons (T161647), and stability reasons as it is very hard to change a class in a way that doesn't break forward or backward compatibility with cached objects of that class (e.g., T264257 etc.).
Code that writes to or reads from a cache must be both forward- and backward compatible. Typically, the code reading cached data will have the same or a newer than the code that wrote the cached data (requiring backward compatible read logic, or forwards-compatible writing ahead of time), but there are two important scenarios where the opposite is also needed:
- During a deployment, different servers and data centers briefly run old and new versions side-by-side with the same shared database and caching services.
As such, a cache may very well be written to and read from both old and new versions concurrently during this time.
- Site operators must be able to roll back the last deployment or upgrade of the software to the previous version.
Best practice:
- Avoid placing version constants inside cache keys. Make use of the
WANObjectCache::getWithSet
idiom and its "version" option, which automatically takes care of forward- and backward compatibility, including invalidating cache keys across versions of the software. - Avoid storing class objects. Store primitives or (nested) arrays of primitives. Classes should be converted to and from simple arrays, and stored either as those simple arrays or as a string of JSON. The encoding and serialising for this must be done by the consumer and is not done by e.g., the BagOStuff or WANObjectCache interfaces. (In the future, MediaWiki may do this automatically for classes that implement JsonUnserializable, which was introduced in MediaWiki 1.36).
Dienste
These are the abstract stores available to MediaWiki features, see the Uses section for examples.
Lokaler Server
- Zugriff über
MediaWikiServices->getLocalServerObjectCache()
. - Konfigurierbar: Nein (wird automatisch erkannt).
- Behaviour: very fast (<0.1ms, from local memory), low capacity, not shared between application servers.
Values in this store are only kept in the local RAM of any given web server (typically using php-apcu). These are not replicated to the other servers or clusters, and have no update or purge coordination options.
If the web server does not have php-apcu (or equivalent) installed, this interface falls back to an empty placeholder where no keys are stored. It is also set to an empty interface for maintenance scripts and other command-line modes. MediaWiki supports APCu, and WinCache.
Lokaler Cluster
The local cluster cache is typically backed by Memcached, but may also use the database.
- Zugriff über
MediaWikiServices->getObjectCacheFactory()->getLocalClusterInstance()
. - Konfigurierbar: Ja, über $wgMainCacheType .
- Behaviour: fast (~1ms, from service memory), medium capacity, shared between application servers but not replicated across data centers.
WAN-Cache
- Zugriff über
MediaWikiServices->getMainWANObjectCache()
. - Konfigurierbar: Ja, über $wgMainWANCache, welches standardmäßig $wgMainCacheType ist.
- Behaviour: fast (~1ms, from service memory), medium capacity, shared between application servers, with invalidation events being replicated across data centers
Values in this store are stored centrally in the current data centre (typically using Memcached as backend). While values are not replicated to other clusters, "delete" and "purge" events for keys are broadcasted to other data centres for cache invalidation. See WANObjectCache class reference for how to use this.
In short: Compute and store values via the getWithSet
method.
To invalidate caches, use key purging (not by setting a key directly).
Siehe auch WANObjectCache auf wikitech.wikimedia.org.
MicroStash
- Accessed through
MediaWikiServices->getMicroStash()
. - Configurable: Yes, via $wgMicroStashType , which defaults to
CACHE_ANYTHING
. - Behaviour: fast (~1ms, from service memory), medium capacity, shared between application servers, with invalidation done via TTL. Data stored will only be evicted only when the TTL expires regardless of if or not the data gets used.
Values in this store are stored centrally in the primary data centre (typically using Memcached as backend). Values are not replicated to other data centers, and data gets evicted only when the time to live (TTL) elapses.
Main stash
- Zugriff über
MediaWikiServices->getMainObjectStash()
. - Konfigurierbar: Ja, über $wgMainStash.
- Behaviour: may involve disk read (1-10ms), semi-persistent, shared between application servers and replicated across data centers.
Values in this store are read and written in the same data centre, with writes expected to be replicated to and from other data centres. It typically uses MySQL as backend. (See wikitech:MariaDB#x2 for Wikipedia's configuration.) By default, the objectcache table is used. It must be tolerated that reads can potentially be stale, for example due to brief unavailability of cache writes, or race conditions where overlapping requests finish out of order, or due to writes from another data center taking a second to replicate.
This store is expected to have strong persistence and is often used for data that cannot be regenerated and is not stored elsewhere. However, data stored in the MainStash must be non-critical and result in minimal user impact if lost, thus allowing for the backend to sometimes be partially unavailable or wiped if under operational pressure without causing incidents.
Uses
Session store
- Accessed via
Session
objects, which itself is accessed via SessionManager, orRequestContext->getRequest()->getSession()
- Configured via
$wgSessionCacheType
.
This is not really a cache, in the sense that the data is not stored elsewhere.
Interwiki-Cache
See Interwiki cache for details, and also ClearInterwikiCache.php.
Parser-Cache
- Accessed via the
ParserCache
class. - Backend configured by
$wgParserCacheType
(typically MySQL). - Keys are canonical by page ID and populated when a page is parsed.
- Revision ID is verified on retrieval.
See Manual:Parser cache for details. Siehe auch purgeParserCache.php.
Nachrichten-Cache
- Zugriff über
MessageCache
. - Backend configurable by $wgMessageCacheType (defaults to $wgMainCacheType, with fallback to MySQL).
Revision text
- Zugriff über
SqlBlobStore::getBlob
. - Stored in the WAN cache, using key class
SqlBlobStore-blob
. - Keys are verifiable and values immutable. Cache is populated on demand.
Background
The main use case for caching revision text (as opposed to fetching directly from the text table or External Storage) is for handling cases where the text of many different pages is needed by a single web request.
- Originally implemented in 2006 (r16549, commit 376014e).
- Process cache added in 2016 (git #I77575d6, git #Ic61ee91).
- Adopted by MessageCache in 2017 (git #Ib668e69).
This is primarily used by:
- Parsing wikitext. When parsing a given wiki page, the Parser needs the source of the current page, but also recursively needs the source of all transcluded template pages (and Lua module pages). It is not unusual for a popular article to indirectly transclude over 300 such pages. The use of Memcached saves time when saving edits and rendering page views.
- MessageCache. This is a wiki-specific layer on top of LocalisationCache, which consists primarily of message overrides from "MediaWiki:"-namespace pages on the given wiki. When building this blob, the source text of many different pages needs to be fetched. This is cached per-cluster in Memcached, and locally per-server (to reduce Memcached bandwidth ; r11678, commit 6d82fa2).
Beispiel
Key WANCache:v:global:SqlBlobStore-blob:<wiki>:<content address>
.
"content address" refers to the content.content_address
on the wiki's main database (e.g. "tt:1123").
This in turn refers to the text table or (External Storage).
To reverse engineer which page/revision this relates to, Find content.content_id
for the content address (SELECT content_id FROM content WHERE content_address = "tt:963546992";
), then find the revision ID for that content slot (SELECT slot_revision_id FROM slots WHERE slot_content_id = 943285896;
).
The revision ID can then be used on-wiki in a url like https://en.wikipedia.org/w/index.php?oldid=951705319, or you can look it up in the revision and page tables.
Revision meta data
- Zugriff über
RevisionStore::getKnownCurrentRevision
. - Stored in the WAN cache, using key class
revision-row-1.29
. - Keys are verifiable (by page and revision ID) and values immutable. Cache is populated on demand.
MessageBlobStore
Stores interface text used by ResourceLoader modules. It is similar to LocalisationCache, but includes the wiki-specific overrides. (LocalisationCache is wiki-agnostic). These overrides come from the database as wiki pages in the MediaWiki-namespace.
- Zugriff über
MessageBlobStore
. - Stored in the WAN cache, using key class
MessageBlobStore
. - Keys are verifiable (by ResourceLoader module name and hash of message keys). Values are mutable and expire after a week. Cache populated on demand.
- All keys are purged when LocalisationCache is rebuild. When a user save a change to a MediaWiki-namespace page on the wiki, a subset of the keys are also purged.
Minification cache
ResourceLoader caches the minified versions of raw JavaScript and CSS input files.
- Zugriff über
ResourceLoader::filter
. - Stored locally on the server (APCu).
- Keys are verifiable (deterministic value). No purge strategy needed. Cache populated on demand.
LESS compilation cache
ResourceLoader caches the meta data and parser output of LESS files it has compiled.
- Zugriff über
ResourceLoaderFileModule::compileLessFile
. - Stored locally on the server (APCu).
File content hasher
ResourceLoader caches the checksum of any file directly or indirectly used by a module. When serving the startup manifest to users, it needs the hashes of many thousands of files. To reduce I/O overhead, it caches this content hash locally, keyed by path and mtime.
- Zugriff über
FileContentsHasher
. - Stored locally on the server (APCu).
Siehe auch
- Handbuch:Architekturelle Module/Cache
- Handbuch:Performance tuning - How to configure your web server and/or cache proxy and MediaWiki; to improve performance.
- Manual:File cache - Simplistic cache mechanism that caches HTTP responses on-disk.
- Manual:Configuration settings#Cache: Various configuration settings to set up caching backends and enable parts of the application to use them.
- Wikimedia BagOStuff (ObjectCache) , the library providing this functionality