Object cache/cs

Mezipaměť MediaWiki využívá u mnoha komponent a na více úrovních. A tato stránka dokumentuje, co a jak se PHP aplikace MediaWiki k tomu používá.

Obecné
V kontextu mezipaměti objektů na MediaWiki jsou popsány dva druhy úložišť:


 * 1) Cache, (keš) česky také nazývaná mezipaměť, je místo, do kterého se ukládá výsledek výpočtu a data získaná z externího zdroje (aby se dosáhlo co možná nejvyšší rychlosti při zpracovávání uložených dat). Toto je "mezipaměť" v definici informatiky.
 * 2) Stash (angl. slovo "stash" (steš) v čeština znamená skrýš) je místo, na které se ukládají z výpočetního hlediska nenáročná data, která se už nikam jinam neukládají. Někdy se také označuje angl. slovem hoard, neboli zásobárna objektů. Ukládá se do ní vše, co není nutné znova zdlouhavě generovat, protože by se tím jen zbytečně zatěžoval server.

Terminologie
Klíč, přes který se přistupuje do mezipaměti musí být "verifiable", neboli lehce "ověřitelný", aby si mohla aplikace snadno a rychle ověřit, že hodnota, zastupovaná klíčem ještě nezastarala.

Platí to i v takovém v případě, kdy klíč zastupuje pouze jedinou možnou hodnotu. Například výpočet čísla π na 100 desetinných míst, lze uložit do mezipaměti pod klíčem. Výsledek této operace můžeme bez problému uložit do úložiště s vysokorychlostním přístupem bez jakékoliv další koordinace s jinými komponentami, jelikož ho už nikdy víc nebude potřeba aktualizovat či odstranit. A pokud jeho platnost v mezipaměti vyprší, dá se vypočítat znovu a výsledek bude stále stejný. Totéž platí i pro ukládání wikitextu určité revize stránky. Obsah revize 123 bude také provždy stejný. Pokud tedy aplikace zná ID revize, kterou hledá, lze považovat i klíč typu  za snadno ověřitelný klíč mezipaměti.



Ukládání strukturovaných dat
MediaWiki podporuje ukládání jednoduchých objektů (jako jsou booleanské hodnoty, čísla a řetězce), tak složitě strukturovaných, do sebe zanořených polí. Technicky je možné ukládat také surové objekty (stdClass) a instance libovolných tříd, pokud jsou serializované přes PHP, ovšem tenhle zastaralý přístup nedoporučujeme používat. Jednak z bezpečnostních důvodů (T161647) a ale také s ohledem na stabilitu kódu, protože je pak velmi obtížné změnit třídu tak, aniž by tím nebyla narušena dopředná či zpětná kompatibilita kódu s objekty této třídy které jsou uloženy v mezipaměti (viz T264257 atd.).

Kód, který se zapisuje do mezipamšti nebo se z ní načítá, musí být vždy kompatibilní oběma směry. Typicky, kód, který data z mezipaměti načítá je obvykle novější než ten, který je do mezipaměti zapsal, což pochopitelně vyžaduje aby byl zpětně kompatibilní aby je dokázal přečíst a zároveň je zapisoval tak, aby s jejich načtením v budoucnu nebyl problém. Ovšem existují dvě důležité situace, kdy je potřeba opačný přístup:
 * 1) Během distribuce kódu běží na serverech a datových centrech po nějaký čas paralelně stará a nová verze kódu, která sdílí stejnou databázi a kešovací služby. A během této doby tak může s keší  souběžně pracovat stará i nová verze.
 * 2) Provozovatelé webů tak musí mít možnost vrátit poslední změnu či aktualizaci softwaru zpět na předchozí verzi.

Osvědčené postupy:


 * Nepoužívejte tedy k sestavení klíčů pro kešované objekty konstanty či proměnné, jejichž hodnoty se mohou časem změnit. Využijte místo toho  a volbu "version", která automaticky zajistí, že zůstane zachována dopředná i zpětná kompatibilita, a dojde k bezproblémovému zneplatnění kešovacího klíče bez ohledu na verzi aktuálně používaného software.
 * Vyhněte se také ukládání objektů typu class (třída). Ukládejte primitiva, stabilní, neměnná data, a klidně i (vnořená) pole naplněná primitivy. Třídy je sice možné převádět do podoby jednoduchých polí a tyto pole ukládat, ať už ve formě řetězců, či dat ve formátu JSON. Ovšem zakódování a jejich serializaci aby to bylo možné musí dělat ten kdo s nimi pracuje a ne BagOStuff nebo rozhraní WANObjectCache. (Ale nelze vyloučit, že v budoucnu MediaWiki možná bude automaticky využívat pro ukládání tříd metodu JsonUnserializable, neboť je součástí MediaWiki od verze 1.36).

Služby
Jedná se o abstraktní úložiště, které je dostupné pro různé funkcionality MediaWiki, jejich příklady naleznete v části Použití.



Úložiště na lokálním serveru

 * Dostupné skrze.
 * Možnost parametrizace: Žádná (je detekováno automaticky)
 * Chování: velmi rychlé (<0.1ms, načítá se z lokální paměti), malá kapacita, s ostatními aplikačními servery se nic nesdílí.

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.



Úložiště na lokálním clusteru

 * Dostupné přes.
 * Možnost parametrizace: Ano, přes $wgMainCacheType.
 * Chování: rychlé (~1ms, načítá se z paměti poskytované služby), kapacita střední, data se sdílejí mezi aplikačními servery, ale nereplikují napříč datovými centry.

Mostly for internal use only, to offer limited coordination of actions within a given data centre. This uses the same storage backend as WAN cache, but under a different key namespace, and without any ability to broadcast purges to other data centres.

The local cluster cache is typically backed by Memcached, but may also use the database.



Kešování na úrovni WAN

 * Dostupné skrze.
 * Možnost parametrizace: Ano, prostřednictvím $wgMainWANCache, což je výchozí pro $wgMainCacheType.
 * Chování: rychlé (~1ms, načítá se z paměti poskytované služby), kapacita střední, data se sdílejí mezi aplikačními servery, při použití zneplatňovacích událostí mohou být replikována data napříč datovými centry.

Data v tomto úložišti jsou uložena centrálně v aktuálním datovém centru (typicky se využívá jako backend Memcached). 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  method. To invalidate caches, use key purging (not by setting a key directly).

See also WANObjectCache on wikitech.wikimedia.org.

Main stash

 * Accessed through.
 * Configurable: Yes, via $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 MariaDB for Wikipedia's configuration.) By default, the table is used. It must be tolerated that reads can potentially be stale, for example due to bried 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.

Použití


Úložiště sezení
Nejde o skutečnou keš v tom smyslu, že by tahle data byla skutečně někde uložena.
 * Je dostupné výhradně prostřednictvím objektu, ke kterému se přistupuje přes správce relací (též sezení) (objekt SessionManager), který lze získat přes
 * Nastavuje se přes.



Kešování Interwiki
Více viz na stránce věnované kešování Interwiki a v kódu údržbářského skriptu.



Kešování analyzátoru wikikódu (parser)
Pro další podrobnosti viz Příručka:Parser a jeho keš. Viz též kód údržbářského skriptu purgeParserCache.php.
 * Přistupuje se k němu přes třídu.
 * Jde v podstatě o rozhraní k 'backendu', kterým je obvykle nějaká databáze (typicky MySQL), který se nastavuje přes proměnnou.
 * Klíče jsou pevně dané. Odpovídají ID stránky a data se ukládají jakmile je kód stránky zpracován analyzátorem (parser).
 * ID revize se ověřuje při načítání.



Kešování zpráv

 * Dostupné přes.
 * Backend configurable by $wgMessageCacheType (defaults to $wgMainCacheType, with fallback to MySQL).

Revision text

 * Accessed via.
 * Stored in the WAN cache, using key class.
 * 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  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 (, commit 376014e).
 * Process cache added in 2016.
 * Adopted by MessageCache in 2017.

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 ;, commit 6d82fa2).

Příklad
Klíč.

"content address" refers to the  on the wiki's main database (e.g. "tt:1123"). This in turn refers to the table or (External Storage).

To reverse engineer which page/revision this relates to, Find  for the content address, then find the revision ID for that content slot.

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

 * Accessed via.
 * Stored in the WAN cache, using key class.
 * 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.


 * Accessed via.
 * Stored in the WAN cache, using key class.
 * 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.
 * Accessed via.
 * 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.


 * Accessed via.
 * 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.


 * Accessed via.
 * Stored locally on the server (APCu).



Viz též

 * Architectural modules/Cache
 * Manual: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.
 * ObjectCache, the library providing this functionality