Manual:Memcached/cs

From Linux Web Expert

memcached je úložiště objektů v paměti, které může MediaWiki použít pro hodnoty ukládání do mezipaměti, aby se snížila potřeba provádět náročné výpočty a snížilo zatížení databázových serverů.

Kdy použít

Pro malý web hostovaný jediným serverem nemusí instalace Memcached stát za potíže. V takových případech zvažte konfiguraci MediaWiki tak, aby místo hlavního úložiště objektů používala APCu PHP. Pro velké webové stránky, jako je Wikipedie a obecně pro wikiny hostované více webovými servery, je Memcached běžnou volbou pro mezipaměť objektů MediaWiki.

Další informace o možnostech ukládání do mezipaměti v MediaWiki naleznete na stránce Příručka:Ladění výkonu § Ukládání objektů do mezipaměti

Jak nainstalovat Memcached

Většina správců balíčků pro Linux a macOS má k dispozici balíčky připravené k použití pro Memcached (včetně Debianu, Fedory a Ubuntu).

Pokud pro vaši distribuci není k dispozici žádný balíček, možná jej budete muset zkompilovat ze zdroje stažením z memcached.org. Ke kompilaci ze zdroje budete také potřebovat libevent. Memcached a libevent jsou projekty s otevřeným zdrojovým kódem vydané pod licencemi ve stylu BSD.

Pro více informací o Memcached obecně viz také "Memcached" na Wikipedii.

Zabezpečení

Memcached nemá žádné zabezpečení ani ověřování. Ujistěte se prosím, že váš server je správně zabezpečen firewallem a že porty používané pro servery s memcachingem nejsou veřejně přístupné. Jinak může kdokoli na internetu vkládat data do vaší mezipaměti a číst je.

Útočník obeznámený s interními informacemi MediaWiki by toho mohl využít k tomu, aby si udělil přístup pro vývojáře a smazal všechna data z databáze wiki a také získal hash hesel všech uživatelů a e-mailové adresy.

PHP klient pro Memcached

V době psaní tohoto článku (MediaWiki 1.27) používá MediaWiki čistě PHP klienta memcached (na základě práce Ryana T. Deana). Podporuje také rozšíření PECL php-memcached. Chcete-li používat Memcached s MediaWiki, PHP musí být zkompilováno s --enable-sockets (toto je výchozí nastavení).

Chcete-li si přečíst více o tom, jak vybrat Memcached jako backend pro různé části MediaWiki, viz Příručka:Ukládání do mezipaměti.

Nastavení

Pokud chcete začít v malém, stačí spustit jeden memcached na vašem webovém serveru:

 memcached -d -l 127.0.0.1 -p 11211 -m 64

(pro spuštění v režimu daemon, přístupné pouze přes rozhraní zpětné smyčky, na portu 11211, s využitím až 64 MB paměti)

V souboru LocalSettings.php nastavte:

$wgMainCacheType = CACHE_MEMCACHED;
$wgParserCacheType = CACHE_MEMCACHED; // volitelné
$wgMessageCacheType = CACHE_MEMCACHED; // volitelné
$wgMemCachedServers = [ '127.0.0.1:11211' ];

$wgSessionsInObjectCache = true; // volitelné -- odstraněno ve verzi 1.33+
$wgSessionCacheType = CACHE_MEMCACHED; // volitelné

Wiki by pak měla používat memcached k ukládání různých dat do mezipaměti. Chcete-li použít více serverů (fyzicky oddělené boxy nebo více mezipamětí na jednom počítači na x86 / Power box s velkou pamětí), stačí přidat do pole více položek. Chcete-li zvýšit váhu serveru (řekněme proto, že má dvojnásobnou paměť než ostatní a chcete rovnoměrně rozložit využití), udělejte z jeho položky podpole:

$wgMemCachedServers = [
    '127.0.0.1:11211', // 1 GB na tomto boxu
    [ '192.168.0.1:11211', 2 ] // 2 GB na druhém boxu
];

SELinux

Pro systémy se SELinuxem existuje několik zásad pro Memcached. Chcete-li povolit Apache (httpd) přístup k Memcached, musíte nastavit následující zásady:

 setsebool -P httpd_can_network_memcache 1

Řešení problémů

Ztráta dat relace při ukládání

Pokud ukládáte data relace do memcached a uživatelům se při pokusu o uložení úprav občas zobrazí tato zpráva:

Sorry! We could not process your edit due to a loss of session data.

You might have been logged out. Please verify that you're still logged in and try again. If it still does not work, try logging out and logging back in, and check that your browser allows cookies from this site.

Pak jeden nebo více vašich serverů memcached může mít špatně nakonfigurovaný soubor /etc/hosts. Na každém z vašich serverů memcached se ujistěte, že je vlastní název hostitele serveru namapován na localhost:

127.0.0.1  servername.here localhost localhost.localdomain ...

V opačném případě se server nemusí být schopen připojit ke svému vlastnímu procesu v memcached.

Použití memcached ve vašem kódu

Pokud píšete rozšíření, které provádí náročné databázové dotazy, může být užitečné ukládat data do mezipaměti v memcached. Existuje několik hlavních způsobů, jak získat rukojeť pro memcached:

  • $cache = ObjectCache::getMainWANInstance()
    
    ...použijte toto, pokud chcete sdílenou mezipaměť založenou na paměti s explicitní schopností čištění za účelem ukládání hodnot odvozených z trvalých zdrojů
  • $cache = ObjectCache::getLocalClusterInstance()
    
    ...toto použijte, pokud chcete pomíjivé úložiště založené na paměti, které není sdíleno mezi datovými centry
  • $cache = ObjectCache::getLocalServerInstance()
    
    ...toto použijte, pokud chcete dočasnou mezipaměť založenou na paměti, která není sdílena mezi webovými servery
  • $cache = wfGetCache( CACHE_ANYTHING )
    
    ...toto použijte, pokud chcete jakoukoli dostupnou mezipaměť, která může nebo nemusí být pro jednotlivá datacentra, dokonce i emulovaná, která používá databázi SQL. Všimněte si, že tyto mohou vracet ovladače, které místo toho komunikují s Redis, APC, MySQL nebo jinými místy. Použití slova "memcached" je historicky způsobeno tím, že API je definováno kolem jednoduchých příkazů, které memcached podporuje, a skutečnosti, že k dnešnímu dni je memcached obvykle nejlepším univerzálním úložištěm mezipaměti.

Rozšíření, která mají specifické potřeby (např. persistence), by měla definovat nová nastavení konfigurace, jako je $wgMyExtCache nebo $wgMyExtWANCache. Kód využívající mezipaměti je může předat na wfGetCache() a ObjectCache::getWANInstance(), v tomto pořadí.

Následující úryvek kódu ukazuje, jak uložit výsledky databázového dotazu do mezipaměti do memcached po dobu 15 minut a nejprve se dotazovat memcached na výsledky místo do databáze.

class MyExtensionFooBars {
	public function getPopularTen() {
		$cache = ObjectCache::getMainWANInstance();
		
		return $cache->getWithSetCallback(
			// Variadic argumenty wfMemcKey() se používají k vytvoření klíče pro mezipaměť v memcached. 
			// Musí být jedinečný pro dotaz, který ukládáte.
			// První hodnota je obvykle název rozšíření nebo součásti, 
            // a následující hodnoty vám řeknou, jaký dotaz ukládáte.
			$cache->makeKey( 'myextension', 'foobars', 'popular', '10' ),
			// Uložit do mezipaměti na 15 minut
			$cache::TTL_MINUTE * 15,
			// Funkce pro generování hodnoty o chybě mezipaměti
			function ( $oldValue, &$ttl, &$setOpts ) {
				$dbr = wfGetDB( DB_REPLICA );
				// Upravte TTL na základě zpoždění replikace DB
				$setOpts = Database::getCacheSetOptions( $dbr );

				$res = $dbr->select(
					// váš databázový dotaz jde sem
					// viz Database::select pro dokumenty
				);

				$data = array();
				foreach ( $res as $row ) {
					$data[] = array(
						// Udělejte něco s daty, které jsme právě získali z databáze.
						// Pokud bychom například vyhledali page_id z tabulky stránek,
						// mohli bychom udělat toto:
						'id' => $row->page_id
					);
				}

				return $data;
			}
		);
	}
}

Abstraktní třídy BagOStuff a WANObjectCache definují a dokumentují všechny dostupné funkce:

Staré vývojové poznámky

Obecně řečeno, rádi bychom mohli ukládat velké množství dat do mezipaměti, používat je, kdykoli je to možné, a automaticky vypršet, když jsou provedeny změny.

Model vypršení platnosti

  • Explicitní časy vypršení platnosti: memcached nám umožňuje nastavit čas vypršení platnosti objektu, když jej ukládáme. Po uplynutí času další požadavek na objekt zjistí, že jeho platnost vypršela, a nic nám nevrátí.
    • pro: last-ditch fallback, který umožňuje, aby data, která "by mohla" být špatně aktualizována, nakonec vypadla z mezipaměti
    • con: musíme vědět předem, kdy přestane být neplatný. Těžko dělat, když máme co do činění s uživatelskými úpravami!
  • odstraní objekty uložené v mezipaměti, když víme, že děláme něco, co způsobí, že budou neplatné, ale nejsme schopni je aktualizovat, když už jsme u toho
    • pro: poměrně jednoduché; položka bude znovu načtena z databáze a znovu načtena, až bude příště potřeba
    • con: pokud to ovlivní velký počet souvisejících položek (například vytvoření nebo smazání stránky znehodnotí tabulky odkazů/přerušených odkazů a vykreslenou mezipaměť HTML stránek, které odkazují na tuto stránku), možná je budeme muset všechny vyhledat a provést spoustu aktualizací
  • zahrnout časová razítka do objektů uložených v mezipaměti a provést vlastní expirace na základě závislostí
    • pro: může vypršet platnost mnoha objektů najednou aktualizací jednoho uzlu, na kterém závisí
    • con: více věcí k načtení; s více závislostmi by mohla být složitější práce

Otázky a odpovědi

Otázka: Mohu hledat na části klíče nebo regulárního výrazu na serveru Memcached?

Odpověď: Ne, přesný klíč můžete vyhledat pouze v případě, že potřebujete více informací o tom, co byste mohli udělat, můžete se podívat na Memcached protokol

Otázka: Mohu nechat více wiki odkazovat na stejný server Memcached?

Odpověď: Ano, pokud má každý jiný wiki-id ($wgDBname). Některé klíče mezipaměti jsou v takovém scénáři záměrně sdíleny, například věci omezující rychlost.

Související odkazy