Objektová mezipaměť

This page is a translated version of the page Object cache and the translation is 100% complete.

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 math_pi_digit:100. 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 revision_content:123 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 služby mezipaměti.

    A během této doby tak může s mezipamětí 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 objekty mezipaměti konstanty či proměnné, jejichž hodnoty se mohou časem změnit. Využijte místo toho WANObjectCache::getWithSet 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í klíče mezipaměti 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é přes MediaWikiServices->getLocalServerObjectCache() nebo MediaWikiServices->getObjectCacheFactory()->getLocalServerInstance( $fallback );.
  • 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í.

Hodnoty v tomto uložišti jsou uchovávány pouze v místní paměti RAM libovolného webového serveru (obvykle pomocí php-apcu). Ty se nereplikují na jiné servery nebo clustery a nemají žádné možnosti koordinace aktualizace nebo čištění.

Pokud webový server nemá nainstalovaný php-apcu (nebo ekvivalent), toto rozhraní se vrátí zpět na prázdný zástupný symbol, kde nejsou uloženy žádné klíče. Je také nastaveno na prázdné rozhraní pro skripty údržby a další režimy příkazového řádku. MediaWiki podporuje APCu a WinCache.

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

  Varování: Většinou pro pouze interní použití, aby nabídla omezenou koordinaci akcí v rámci daného datového centra. To používá stejný backend úložiště jako mezipaměť WAN, ale pod jiným klíčovým jmenným prostorem a bez jakékoli možnosti vysílat čištění do jiných datových center.

Lokální klastrová mezipaměť je obvykle zálohována Memcached, ale může také používat databázi.

  • Dostupné přes MediaWikiServices->getObjectCacheFactory()->getLocalClusterInstance().
  • 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.

Mezipaměť na úrovni WAN

  • Dostupné přes MediaWikiServices->getMainWANObjectCache().
  • 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). Zatímco hodnoty nejsou replikovány do jiných klastrů, události "delete" a "purge" pro klíče jsou vysílány do jiných datových center pro zneplatnění mezipaměti. Jak to použít, viz WANObjectCache odkaz na třídu.

Stručně řečeno: Počítejte a ukládejte hodnoty pomocí metody getWithSet. Chcete-li zneplatnit mezipaměti, použijte čištění klíčů (nikoli přímým nastavením klíče).

Viz také WANObjectCache na wikitech.wikimedia.org.

MicroStash

  • Dostupné přes MediaWikiServices->getMicroStash().
  • Možnost parametrizace: Ano, prostřednictvím $wgMicroStashType , což je výchozí pro CACHE_ANYTHING.
  • Chování: rychlé (~1 ms, ze servisní paměti), střední kapacita, sdílené mezi aplikačními servery, s neplatností provedenou prostřednictvím TTL. Uložená data budou vyřazena pouze tehdy, když vyprší TTL, bez ohledu na to, zda budou nebo nebudou data použita.

Hodnoty v tomto úložišti jsou uloženy centrálně na aplikačních serverech (obvykle pomocí Memcached jako backend). Zatímco hodnoty nejsou replikovány do jiných datových center, data se vystěhují pouze po uplynutí doby životnosti (TTL).

Hlavní uložiště

  • Dostupné přes MediaWikiServices->getMainObjectStash().
  • Možnost parametrizace: Ano, přes $wgMainStash.
  • Chování: Může zahrnovat čtení disku (1-10 ms), semiperzistentní, sdílené mezi aplikačními servery a replikované napříč datovými centry.

Hodnoty v tomto úložišti se čtou a zapisují ve stejném datovém centru, přičemž se očekává, že zápisy budou replikovány do a z jiných datových center. Obvykle používá jako backend MySQL. (See wikitech:MariaDB#x2 for Wikipedia's configuration.) Ve výchozím nastavení se používá tabulka objectcache . Je třeba tolerovat, že čtení může být potenciálně zastaralé, například kvůli dočasné nedostupnosti zápisů do mezipaměti nebo použitím, kdy překrývající se požadavky skončí mimo pořadí, nebo kvůli replikaci zápisů z jiného datového centra, které trvá sekundu.

Očekává se, že toto úložiště bude mít silnou perzistenci a často se používá pro data, která nelze regenerovat a nejsou uložena jinde. Data uložená v MainStash však nesmí být kritická a v případě ztráty musí mít minimální dopad na uživatele, což umožňuje, že backend, pokud je pod provozním tlakem, někdy bude částečně nedostupný nebo vymazán aniž by došlo k incidentům.

Použití

Úložiště relací

  • Je dostupné výhradně prostřednictvím objektu Session, ke kterému se přistupuje přes správce relací (též uložiště) (objekt SessionManager), který lze získat přes RequestContext->getRequest()->getSession()
  • Nastavuje se přes $wgSessionCacheType .

Nejde o skutečnou mezipaměť v tom smyslu, že by tahle data byla skutečně někde uložena.

Mezipaměť Interwiki

Více viz na stránce věnované MEZIPAMĚTI Interwiki a v kódu údržbářského skriptu ClearInterwikiCache.php.

Mezipaměť analyzátoru wikikódu (parseru)

  • Přistupuje se k němu přes třídu ParserCache.
  • Jde v podstatě o rozhraní k 'backendu', kterým je obvykle nějaká databáze (typicky MySQL), který se nastavuje přes proměnnou $wgParserCacheType .
  • 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 (parserem).
  • ID revize se ověřuje při načítání.

Pro další podrobnosti viz Příručka:Parser a jeho mezipaměť. Viz též kód údržbářského skriptu purgeParserCache.php.

Mezipaměť zpráv

Text revize

  • Dostupné přes SqlBlobStore::getBlob.
  • Uloženo v mezipaměti WAN pomocí třídy klíče SqlBlobStore-blob.
  • Klíče jsou ověřitelné a hodnoty neměnné. Mezipaměť se plní na vyžádání.

Pozadí

Hlavním případem použití pro ukládání textu revize do mezipaměti (na rozdíl od načítání přímo z tabulky text nebo Externí úložiště) je řešení případů, kdy je jedním webovým požadavkem potřebný text mnoha různých stránek.

Toto primárně využívají:

  • Analýza wikitextu. Při analýze dané wiki stránky potřebuje analyzátor zdroj aktuální stránky, ale také rekurzivně potřebuje zdroj všech transkludovaných stránek šablon (a Lua modul stránek). Není neobvyklé, že populární článek nepřímo přenese přes 300 takových stránek. Použití Memcached šetří čas při ukládání úprav a vykreslování zobrazení stránek.
  • MessageCache. Toto je vrstva specifická pro wiki nad LocalisationCache, která sestává především z přepisů zpráv ze stránek jmenného prostoru "MediaWiki:" na danou wiki. Při vytváření tohoto objektu blob je třeba načíst zdrojový text mnoha různých stránek. Toto se ukládá do mezipaměti pro každý cluster v Memcached a lokálně pro server (pro snížení šířky pásma Memcached; r11678, předloženo 6d82fa2).

Příklad

Klíč WANCache:v:global:SqlBlobStore-blob:<wiki>:<content address>.

"content address" odkazuje na content.content_address v hlavní databázi wiki (např. "tt:1123"). To zase odkazuje na text tabulku nebo (Externí úložiště).

Chcete-li provést zpětnou analýzu, které stránky/revizi se to týká, vyhledejte content.content_id pro adresu obsahu (SELECT content_id FROM content WHERE content_address = "tt:963546992";) a poté najděte ID revize pro daný obsahový slot (SELECT slot_revision_id FROM slots WHERE slot_content_id = 943285896;).

ID revize pak lze použít na wiki v adrese URL jako https://en.wikipedia.org/w/index.php?oldid=951705319, nebo jej můžete vyhledat v tabulkách revizí a stránky.

Metadata revize

  • Dostupné přes RevisionStore::getKnownCurrentRevision.
  • Uloženo v mezipaměti WAN pomocí třídy klíče revision-row-1.29.
  • Klíče jsou ověřitelné (podle ID stránky a revize) a hodnoty jsou neměnné. Mezipaměť se plní na vyžádání.

MessageBlobStore

Ukládá text rozhraní používaný moduly ResourceLoader. Podobá se LocalisationCache, ale obsahuje přepisy specifické pro wiki. (LocalisationCache je pochybovačná wiki). Tato přepsání pocházejí z databáze jako wiki stránky ve jmenném prostoru MediaWiki.

  • Dostupné přes MessageBlobStore.
  • Uloženo v mezipaměti WAN pomocí třídy klíče MessageBlobStore.
  • Klíče jsou ověřitelné (podle názvu modulu ResourceLoader a hash klíčů zpráv). Hodnoty jsou proměnlivé a jejich platnost vyprší po týdnu. Mezipaměť se plní na vyžádání.
  • Při opětovném sestavení LocalisationCache jsou vymazány všechny klíče. Když uživatel uloží změnu na stránce jmenného prostoru MediaWiki na wiki, podmnožina klíčů se také vyčistí.

Minifikační mezipaměť

ResourceLoader ukládá do mezipaměti minifikované verze nezpracovaných vstupních souborů JavaScriptu a CSS.

  • Dostupné přes ResourceLoader::filter.
  • Uloženo lokálně na serveru (APCu).
  • Klíče jsou ověřitelné (deterministická hodnota). Není potřeba žádná strategie čištění. Mezipaměť se plní na vyžádání.

LESS mezipaměti kompilace

ResourceLoader ukládá do mezipaměti metadata a výstup analyzátoru souborů LESS, které zkompiloval.

  • Dostupné přes ResourceLoaderFileModule::compileLessFile.
  • Uloženo lokálně na serveru (APCu).

Hasher obsahu souboru

ResourceLoader ukládá do mezipaměti kontrolní součet jakéhokoli souboru přímo nebo nepřímo používaného modulem. Při doručování spouštěcího manifestu uživatelům potřebuje hash mnoho tisíc souborů. Aby se snížila režie I/O, ukládá tento obsah hash lokálně do mezipaměti, zakódovaný cestou a mtime.

  • Dostupné přes FileContentsHasher.
  • Uloženo lokálně na serveru (APCu).

Související odkazy