Manual:Memcached
memcached es un almacén de objetos en memoria que MediaWiki puede utilizar para almacenar valores en caché, para reducir la necesidad de realizar cálculos costosos y reducir la carga en los servidores de bases de datos.
Cuándo utilizarlo
Para un sitio web pequeño alojado en un único servidor, es posible que no valga la pena instalar Memcached. Para tales casos, considere configurar MediaWiki para usar APCu de PHP como almacén de objetos principal. Para sitios web grandes como Wikipedia y en general para wikis alojados en múltiples servidores web, Memcached es una opción común para la caché de objetos de MediaWiki.
Para más información sobre las opciones de caché en MediaWiki, consulte Manual:Ajuste del rendimiento § Caché de objetos
Instalar Memcached
La mayoría de los gestores de paquetes para Linux y macOS tienen paquetes listos para usar, disponibles para Memcached (incluidos Debian, Fedora y Ubuntu).
Si no hay ningún paquete disponible para su distribución, puede que tenga que compilarlo desde el código fuente descargándolo desde [$1 memcached.org]. Para compilar desde el código fuente también necesitará libevent. Memcached y libevent son proyectos de código abierto liberados bajo licencias de estilo BSD.
Para más información sobre Memcached en general, véase también "Memcached" en Wikipedia.
Seguridad
Memcached no tiene seguridad ni autenticación. Por favor, asegúrese de que su servidor tiene un cortafuegos adecuado, y que los puertos utilizados para los servidores memcached no sean accesibles públicamente. De lo contrario, cualquiera en Internet puede colocar datos y leer datos de su caché.
Un atacante familiarizado con el funcionamiento interno de MediaWiki podría utilizar esto para darse acceso de desarrollador y eliminar todos los datos de la base de datos de la wiki, además de obtener los hashes de contraseñas y las direcciones de correo electrónico de todos los usuarios.
Cliente PHP para Memcached
As of this writing (MediaWiki 1.27), MediaWiki uses a pure-PHP memcached client (based on work by Ryan T. Dean).
También soporta la extensión php-memcached de PECL.
Para usar Memcached con MediaWiki, PHP debe compilarse con --enable-sockets
(este es el predeterminado).
Si desea utilizar el cliente Memcached basado en PECL, establezca $wgMainCacheType
y las variables de caché relacionadas a 'memcached-pecl'
en lugar de CACHE_MEMCACHED
. El cliente PECL Memcached soporta algunas funciones adicionales, como la autorización SASL, que puede ser útil para algunos usuarios.
Para saber más sobre cómo seleccionar Memcached como backend para diferentes partes de MediaWiki, consulte Manual:Caching.
Configuración
Si quiere comenzar poco a poco, sólo ejecute memcached en su servidor web:
memcached -d -l 127.0.0.1 -p 11211 -m 64
(para ejecutarse en modo demonio, accesible sólo a través de la interfaz loopback, en el puerto 11211, utilizando hasta 64MB de memoria)
En su archivo LocalSettings.php, establezca:
$wgMainCacheType = CACHE_MEMCACHED;
$wgParserCacheType = CACHE_MEMCACHED; // opcional
$wgMessageCacheType = CACHE_MEMCACHED; // opcional
$wgMemCachedServers = [ '127.0.0.1:11211' ];
$wgSessionsInObjectCache = true; // opcional -- eliminado en 1.33+
$wgSessionCacheType = CACHE_MEMCACHED; // opcional
La wiki debería entonces utilizar memcached para almacenar varios datos en caché. Para usar varios servidores (máquinas físicamente separadas o múltiples cachés en una sola máquina x86 con mucha memoria o Power box), sólo añada más elementos a la matriz. Para que un servidor tenga mayor relevancia (por ejemplo, porque tiene el doble de memoria que los demás y quiere repartir el uso uniformemente), haga que su entrada sea una submatriz:
$wgMemCachedServers = [
'127.0.0.1:11211', // 1 GB en esta máquina
[ '192.168.0.1:11211', 2 ] // 2 GB en la otra máquina
];
SELinux
Para sistemas con SELinux, hay varias políticas para Memcached. Para permitir que Apache (httpd) acceda a Memcached, debe establecer la siguiente política:
setsebool -P httpd_can_network_memcache 1
Solución de problemas
Pérdida de datos de sesión al guardar
Si almacena datos de sesión en memcached, y los usuarios ven este mensaje de forma intermitente cuando intentan guardar las ediciones:
Lo sentimos, no hemos podido procesar tu edición debido a una pérdida de los datos de sesión.
Puede que se haya cerrado tu sesión. Verifica que hayas accedido e inténtalo de nuevo. Si el problema persiste, prueba a cerrar sesión y volver a acceder. Y verifica que tu navegador permita las cookies de este sitio.
entonces uno o más de sus servidores Memcached podrían tener un archivo /etc/hosts
mal configurado.
En cada uno de sus servidores memcached, asegúrese de que el nombre de equipo del servidor esté mapeado a localhost:
127.0.0.1 servername.here localhost localhost.localdomain ...
De lo contrario, el servidor podría no ser capaz de conectarse a su propio proceso memcached.
Usando memcached en su código
Si está escribiendo una extensión que realiza costosas consultas a bases de datos, puede ser útil que almacene los datos en memcached. Hay algunas formas principales de manejar Memcached:
- ...use this if you want a memory-based shared cache with explicit purge ability in order to store values derived from persistent sources
$cache = ObjectCache::getMainWANInstance()
- ...use this if you want a memory-based ephemeral store that is not shared among datacenters
$cache = ObjectCache::getLocalClusterInstance()
- ...use this if you want a memory-based ephemeral cache that is not shared among web servers
$cache = ObjectCache::getLocalServerInstance()
- ...use this if you want any available cache, which may or may not be per-datacenter, even an emulated one that uses a SQL database. Note that these may return handles that talk to Redis, APC, MySQL or other stores instead. The use of the word "memcached" is historically due to the API being defined around the simple commands that memcached supports and the fact that, to date, memcached is normally the best general-purpose cache store.
$cache = wfGetCache( CACHE_ANYTHING )
Extensions that have specific needs (like persistence) should define new configuration settings like $wgMyExtCache
or $wgMyExtWANCache
.
Code using the caches can pass them to wfGetCache()
and ObjectCache::getWANInstance()
, respectively.
El siguiente fragmento de código demuestra cómo almacenar los resultados de una consulta a la base de datos en memcached durante 15 minutos y consultar primero memcached para obtener los resultados en lugar de la base de datos.
class MyExtensionFooBars {
public function getPopularTen() {
$cache = ObjectCache::getMainWANInstance();
return $cache->getWithSetCallback(
// The variadic arguments to wfMemcKey() are used to construct the key for the cache in memcached.
// It must be unique to the query you are saving.
// The first value is normally the extension or component name, and following values tell you what query you are saving.
$cache->makeKey( 'myextension', 'foobars', 'popular', '10' ),
// Caché durante 15 minutos
$cache::TTL_MINUTE * 15,
// Function to generate the value on cache miss
function ( $oldValue, &$ttl, &$setOpts ) {
$dbr = MediaWikiServices::getInstance()->getConnectionProvider()-> getReplicaDatabase();
// Adjust TTL based on DB replication lag
$setOpts = Database::getCacheSetOptions( $dbr );
$res = $dbr->select(
// your database query goes here
// see Database::select for docs
);
$data = array();
foreach ( $res as $row ) {
$data[] = array(
// Do something with the data we just got from the database.
// For example, if we looked up page_id from the page table, we could do this:
'id' => $row->page_id
);
}
return $data;
}
);
}
}
Las clases abstractas BagOStuff y WANObjectCache definen y documentan todas las funciones disponibles:
Notas de desarrollo antiguas
En términos generales, nos gustaría poder volcar muchos datos en la caché, utilizarlos siempre que podamos y que expiren automáticamente cuando se hagan cambios.
Expiration model
- explicit expiration times: memcached lets us set an expiration time on an object when we store it. After the time is up, another request for the object will find that it has expired and return nothing to us.
- pro: last-ditch fallback to let data that could be updated badly eventually fall out of the cache
- con: we have to know ahead of time when it will cease to be invalid. hard to do when we're dealing with user edits!
- delete cached objects when we know we're doing something that will cause them to be invalid but are not in a position to update them while we're at it
- pro: fairly simple; the item will be reloaded from the database and recached when it's next needed
- con: if this will affect a large number of related items (for instance, creating or deleting a page invalidates the links/brokenlinks tables and rendered HTML cache of pages that link to that page) we may have to hunt them all down and do a lot of updating
- include timestamps on cached objects and do our own expiries based on dependencies
- pro: can expire many objects at once by updating a single node they depend on
- con: more things to load; multiple dependencies could be trickier to work with
Preguntas y respuestas
Q: Can I search on part of a key or a regular expression on a Memcached server?
A: No, you can only search for an exact key if you need more information on what you could possibly do you can check out the Memcached protocol
Q: Can I have multiple wikis point to the same Memcached server?
A: Yes, as long as each have different wiki-ids ($wgDBname ). Certain cache keys are intentionally shared in such a scenario, such as rate limiting stuff.