Memcached - principe de fonctionnement

06 Mar 2013


Cette article est le premier d'une série de trois qui a pour but de présenter Memcached, la gestion de la mémoire et les optimisations possibles.


Présentation

Comme le dit si bien Wikipedia:
"Memcached est un système d'usage général servant à gérer la mémoire cache distribuée. Il est souvent utilisé pour augmenter la vitesse de réponse des sites web créés à partir de bases de données."


Le principe ici est que plutôt que d'aller chercher régulièrement certaines données en base il vaut mieux conserver cette donnée dans la mémoire afin de pouvoir y accéder plus rapidement. De la même façon on peut stocker ainsi le résultat de calculs couteux , des données à écrire en base (pour de l'écriture asynchrone) ou encore des pages web.


Comme indiqué précédemment Memcached est un outil de stockage des données en mémoire de type clé - valeur. La principale conséquence de cela est que si la machine s'arrête on perd l'ensemble des données stockées dans Memcached. Il ne faut donc pas stocker les données importantes uniquement à cet endroit.


Ceci étant dit, Memcached est un outil fantastique pour améliorer la vitesse d'un site pour la bonne et simple raison qu'il est beaucoup beaucoup plus rapide d'accéder à de la mémoire qu'à un disque dur. Voici quelques ordres de grandeurs de temps d'accès:

  • 100 ns (10-7 s): temps d'accès à la mémoire
  • 10 000 000 ns (10-2 s): temps d'accès à un disque dur
Et tout de suite on voit que la mémoire est 100 000 fois plus lente qu'un accès disque disque... Bingo plein de perf' !


L'idée générale de Memcached est d'offrir un outil simple mais très performant afin de profiter au maximum de la vitesse de la mémoire. Il est possible d'accéder à Memcached via la majorité des langages utilisés à l'heure actuelle.

Principe de fonctionnement

Au moment du lancement du processus memcached on lui assigne une taille maximale (via le paramètre -m). Cet espace mémoire est ensuite découpé en page d'une taille fixe de 1 Mio (par défaut). La première conséquence de ce découpage est que l'on ne peut pas stocker dans Memcached des éléments de plus de 1Mio.


Ensuite Memcached découpe ses pages de 1 Mio en éléments appelés des chunks. Un chunk est un espace mémoire de taille fixe qui va stocker la clé, la donnée associée et quelques infos destinées à Memcached. Si l'on spécifie par exemple une taille de chunk de 96 octets (paramètre -n) alors tous les éléments d'une taille (taille de la clé + taille de la donnée + métadonnée Memcached) inférieure à 96 octets occuperont un espace de 96 octets en mémoire.


Tous les éléments d'une même taille sont stockés dans une classe slab. Ainsi notre premier slab contient tous les éléments d'une taille comprise entre 1 et 96 octets.

Lors de l'insertion de la première donnée dans Memcached celui-ci vérifie d'abord à quelle classe appartient l'élément inséré puis décompose une page de 1Mio en chunks de la taille des éléments du slab.
Par exemple avec notre slab contenant des éléments de 96 octets, Memcached découpe sa page de 1 Mio en 10 922 chunks. Une fois les 10 922 chunks remplis Memcached assigne une nouvelle page de 1Mio au slab.


Dans le cas où l'élément fait plus de 96 octets Memcached détermine la taille du slab suivant en utilisant le facteur d'augmentation (paramètre -f). Par exemple avec un facteur de 2 le deuxième slab hébergera des éléments d'une taille maximale de 192 octets mais ne pourra plus héberger que 5461 chunks.


En lançant Memcached avec le paramètre -vv on obtient la taille des différents slabs ainsi que le nombre de chunks pouvant être stocké par page:


~ $ memcached -vv -f 2 -m 512
slab class 1: chunk size 96 perslab 10922
slab class 2: chunk size 192 perslab 5461
slab class 3: chunk size 384 perslab 2730
slab class 4: chunk size 768 perslab 1365
slab class 5: chunk size 1536 perslab 682
slab class 6: chunk size 3072 perslab 341
slab class 7: chunk size 6144 perslab 170
slab class 8: chunk size 12288 perslab 85
slab class 9: chunk size 24576 perslab 42
slab class 10: chunk size 49152 perslab 21
slab class 11: chunk size 98304 perslab 10
slab class 12: chunk size 196608 perslab 5
slab class 13: chunk size 393216 perslab 2
slab class 14: chunk size 1048576 perslab 1
 
On obtient donc 14 classes dont la taille varie entre 96 octets et 1 Mio et pouvant stocker entre 10 922 et 1 élément(s).


Nous avons donc notre espace de stockage mémoire qui écoute par défaut sur le port 11211. Pour insérer et lire des données il suffit d'utiliser l'un des nombreux bindings disponibles dans tous les langages, par exemple l'extension PHP Memcache:


<?php

$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");

// Insert 'data' for 10 seconds in Memcached
$memcache->set('key', 'data', false, 10) or die ("Failed to save data");

$get_result = $memcache->get('key');

var_dump($get_result);

?>
 
Comme on peut le voir on insère des données pour une durée déterminée dans Memcached (maximum 30 jours). Mais que se passe-t-il si malgré tout Memcached vient à manquer de mémoire ?


Il existe alors un ensemble de mécanisme destiné à libérer de la mémoire. C'est ce que nous allons voir dans la deuxième partie: "Memcached: gestion de la mémoire".

Posts  4/52