Cet article fait partie d'une série de trois posts sur Memcached. Il fait suite au premier article: "Memcached: principe de fonctionnement"
Deuxième article sur Memcached et on passe aux choses sérieuses, la gestion de la mémoire par Memcached !
Gestion de la mémoire par Memcached
Expiration
En fonctionnement nominal la mémoire utilisée par les éléments expirés dans Memcached n'est pas réclamée activement. Ainsi même si l'élément est expiré alors sa mémoire ne sera pas libérée immédiatement.Un cas particulier arrive quand on essaye de récupérer un élément expiré. Dans ce cas Memcached va se rendre compte que l'élément est expiré et libérer immédiatement la mémoire utilisée.
Insertion d'un élément dans le cache
Lorsque l'on ajoute un nouvel élément dans Memcached celui-ci vérifie un certain nombre de choses:- Étape 1: Reste-t-il de la place dans la page courante ?
- Étape 2: Reste-t-il des pages mémoires non allouée à un slab ?
- Étape 3: Déclenchement de l'algorithme LRU
Étape 1 : affectation simple
Cette étape est la plus simple et la plus classique: s'il reste de l'espace dans la page courante alors on utilise un chunk de cette page pour stocker notre élément.
Rien de bien compliqué ici !
Étape 2 : assignation d'une page
Nous arrivons dans cette étape s'il n'y a plus de chunk libre dans la page courante. A ce moment Memcached vérifie s'il lui reste des pages mémoire de 1 Mio non affectée au slab courant et si c'est le cas alors il assigne une plage libre au slab courant.
En faisant cela il découpe également cette page en chunk de même taille et utilise un de ces chunk pour stocker l'élément à insérer.
Attention : une fois qu'une page est assignée à un slab cette page ne peut plus être affectée à un autre slab.
Étape 3 : LRU et éviction
S'il n'y a plus de chunk ni de page disponibles alors Memcached va commencer à libérer de l'espace en utilisant un algorithme de type LRU (Least Recently Used). Le principe de cet algorithme est de maintenir une liste d'éléments par date d'utilisation. Ainsi un élément peu utilisé apparaîtra dès le début de cette liste. Memcached va alors parcourir les premiers éléments de la liste et libérer l'espace utilisé par un élément expiré.
La particularité de Memcached est qu'il ne maintient pas une liste globale listant l'ensemble des éléments mais une liste par slab. Ainsi l'algorithme LRU n'est pas global mais local par slab. Memcached conserve une liste d'éléments par slab:
Ainsi dans le scénario 1 l'algorithme LRU va parcourir le début de liste et supprimer l'élément 2 car il est expiré. Dans le scénario 2 au contraire il n'y a pas d'élément expiré dans les premiers éléments de la liste, Memcached va alors "évincer" le premier élément même si celui-ci n'est pas encore expiré. Cette action se nomme une eviction.
Habituellement on n'aime pas trop les évictions car elles correspondent à la suppression d'un élément encore valide dans Memcached. Néanmoins sur certains environnements où la mémoire est limitée ou la quantité d'éléments à stocker est très important il est intéressant de s'appuyer sur ce mécanisme pour conserver dans le Memcached les éléments les plus couramment utilisés et supprimer les autres.
Ce mécanisme fonctionne bien en général mais il peut arriver que malgré tout Memcached manque de mémoire et soit incapable d'en retrouver:
Supposons que l'on dispose de 3 slabs : slab1, slab2 et slab3.
Au démarrage du processus memcached tous les éléments sont insérés dans le slab1 et le slab3 et toute la mémoire allouée à Memcached est utilisée. A ce moment si l'on insère un nouvel élément dans le slab1 ou le slab3 le mécanisme de LRU va se déclencher pour libérer de la mémoire et donc stocker notre élément.
Mais imaginons que l'on souhaite insérer un élément dont la taille le destine à être stocké dans le slab2. Comme il n'est pas possible de réaffecter une page à un autre slab, nous ne pourrons jamais insérer notre nouvel élément dans Memcached et une erreur est renvoyée:
Cette exemple montre bien qu'il est primordial de bien configurer son serveur Memcached afin d'en tirer le maximum. C'est ce que nous allons voir dans la troisième et dernière partie: "Memcached: optimisation".
Posts 5/52