Réplication de serveurs Memcached

C’est la rentrée, j’espère que les vacances se sont bien passées pour tout le monde, et que, comme moi, vous avez énormément pris sur vous en croisant un panneau « Wi-Fi libre accès » sous les regards noirs et appuyés de Madame… :-p (le même regard qu’elle vous jettera d’ailleurs quand, sur la plage, refoulant le souvenir de cette borne Wi-Fi, vos yeux glisseront subrepticement sur le corps de la jeune demoiselle à quelques pas de vous, quand elle dégrafera son haut de maillot de bain…) BREF !!!

Fin de l’encart « vacances perverses » :-D et je vous souhaite une bonne reprise quand même :-)

Nul besoin de vous refaire une présentation de Memcached dont j’avais abordé le sujet précédemment.

Vous l’utilisez parce que vous avez une forte charge sur vos serveurs et vous avez été conquis par ses performances, et c’est bien :-D

Comme vous le savez, fidèles lecteurs (ou pas) de ce blog (et je vous en remercie, c’est toujours très agréable de savoir que le temps passé a tester et écrire des articles est au moins lu par quelques milliers dizaines de personnes :-) ), j’aborde assez souvent la notion de haute-disponibilité.

Outre l’incomparable avantage de permettre au Sysadmin de pouvoir terminer sa nuit tranquillement sans devoir se rendre a 4h du matin au Datacenter pour remettre en service un serveur capricieux, elle permet surtout de disposer d’une infrastructure solide et disponible de façon quasi-permanente qui feront les joies de votre DI/RSI/DRH/DAF etc. etc. (liste non exhaustive).

Dans cette architecture hautement disponible, vous avez greffé un serveur memcached (ou pour soulager vos serveurs de base de données, ou pour distribuer du contenu statique, ou gérer vos sessions utilisateurs, ou que sais-je encore…).

Oui mais voila, si le serveur Memcached tombe, et bien ca colle quand même un frein à vos performances en attendant qu’il reparte.

Nous aurions bien évidemment pu installer un deuxième serveur Memcached en secours et basculer une ip flottante type fail-over/carp sur l’esclave en cas de panne du Maître mais il faut repeupler le cache… Pas très sexy comme méthode (même si efficace).

Je vous propose donc une autre solution, une réplication Memcached entre X serveurs de ce type.

(et là vous pouvez faire « Oooohhh »)

  • REPCACHED

Pour cette solution, nous allons utiliser le projet REPCACHED qui ajoute a Memcached les fonctions de réplication dont vous trouverez les sources sur :

http://sourceforge.net/projects/repcached/files/

Parmi ses fonctionnalités :

  • multi master replication.
  • asynchronous data replication.
  • support all memcached command (set, add, delete, incr/decr, flush_all, cas)

Par contre, si l’on peut reprocher quelque chose à ce projet dans l’état actuel des choses, c’est son manque quasi total de documentation :-(

Deux types de sources sont disponibles :

- 1 patch version 2.2 pour Memcached (version 1.2.8 à l’heure où j’écris)

ou

- L’ensemble complet Repcached 2.2 + Memcached 1.2.8

Le seul pré-requis est d’avoir l’API libevent (un apt-get install libevent-dev sous Debian suffira)

L’installation en mode patch est la suivante :

$ wget http://memcached.googlecode.com/files/memcached-1.2.8.tar.gz
$ tar zxf memcached-1.2.8.tar.gz
$ cd memcached-1.2.8.tar.gz
$ wget http://downloads.sourceforge.net/project/repcached/repcached/2.2-1.2.8/repcached-2.2-1.2.8.patch.gz
$ gzip -cd repcached-2.2-1.2.8.patch.gz | patch -p1

Pour les deux modes (patch ou full sources) :

$ ./configure --enable-replication
$ make
$ make install

Désormais, vous avez des options supplémentaires pour le lancement du démon :

Guiguiabloc-a:/opt/memcached/bin$ ./memcached -h
memcached 1.2.8
repcached 2.2
...
-x   hostname or IP address of peer repcached
-X       TCP port number for replication (default: 11212)

Le fonctionnement est assez basique.

Vous démarrez le premier serveur en lui passant l’option -x adresse_ou_ip_partenaire

memcached@Guiguiabloc-a:~/bin$ ./memcached -d -x Guiguiabloc-b
memcached@Guiguiabloc-a:~/bin$

Le serveur Memcached utilise par défaut le port 11212 pour la réplication, pensez à ouvrir votre firewall.

Maintenant nous allons démarrer le deuxième serveur en lui passant l’option -x

memcached@Guiguiabloc-b:~/bin$ ./memcached -d -x Guiguiabloc-a
memcached@Guiguiabloc-b:~/bin$

Ne reste qu’à tester.

Injectons un couple clé/valeur sur le maître directement par telnet.

NB: Vous trouverez sur http://lzone.de/articles/memcached.htm un récapitulatif des commandes existantes (Merci a Fred (le seul geek que je connaisse qui écoute « Oh chéri chéri » de Karen Cheryl » en boucle sur son Ipod) pour le lien)

memcached@Guiguiabloc-a:~/bin$ telnet Guiguiabloc-a 11211
Trying 192.168.50.1...
Connected to guiguiabloc-a.
Escape character is '^]'.
get url
END
set url 1 0 19
blog.guiguiabloc.fr
STORED
get url
VALUE url 1 19
blog.guiguiabloc.fr
END

En détails, je vérifie s’il existe une valeur pour la clé « url » (get url).

La réponse est négative, je stocke donc la clé « url », 1 signifiant « arbitrary metadata », 0 « n’expire jamais », 19 bytes de longueur, et la valeur.

On redemande la clé « url », c’est bon.

Maintenant sur le deuxième serveur :

memcached@Guiguiabloc-b:~/bin$ telnet guiguiabloc-b 11211
Trying 192.168.50.2...
Connected to guiguiabloc-b.
Escape character is '^]'.
get url
VALUE url 1 19
blog.guiguiabloc.fr
END

Un succès ! :-D

Vous pouvez tester dans l’autre sens, en modifiant la valeur de la clé « url » sur le deuxième serveur, elle sera modifiée sur le premier.

En coupant brutalement l’un des deux et en le relancant, vous verrez que son cache se met a jour automatiquement via la réplication Memcached.

memcached@Guiguiabloc-a:/opt$ telnet guiguiabloc-a 11211
Trying 192.168.50.1...
Connected to Guiguiabloc-a.
Escape character is '^]'.
get url
VALUE url 1 19
blog.guiguiabloc.fr
END
quit
Connection closed by foreign host.
memcached@Guiguiabloc-a:/opt$ killall memcached
memcached@Guiguiabloc-a:/opt$ ps aux | grep memcached
1002      5927  0.0  0.2   4168  1068 pts/0    S    19:26   0:00 su - memcached
1002      5966  0.0  0.1   3344   744 pts/0    S+   19:39   0:00 grep memcached
memcached@Guiguiabloc-a:~/bin$ ./memcached -d -x guiguiabloc-b
memcached@Guiguiabloc-a:~/bin$ telnet guiguiabloc-a 11211
Trying 192.168.50.1...
Connected to guiguiabloc-a.
Escape character is '^]'.
get url
VALUE url 1 19
blog.guiguiabloc.fr
END

Bilan, un excellent outil de haute-disponibilité qui inclut enfin le double sens de réplication (dans les versions antérieures (1.0), il fallait définir le Maître en le démarrant sans paramètres et l’esclave en lui passant l’option -x. En cas de crash du Maître, l’esclave devenait Maître. Le failback se réglait en lancant l’ancien Maître avec l’option -x.

On peut juste regretter l’absence quasi totale de documentation et même si le projet a bientôt 2 ans, il semble particulièrement mature pour de la production. A suivre donc.

Amusez-vous bien :-D

Ce billet a été posté dans architecture, linux et taggé , . Bookmark ce permalink.

8 commentaires sur “Réplication de serveurs Memcached

  1. Très bonne solution, sera très rapidement testé chez moi.
    J’aimerais bien discuter avec toi Guigui, peux-tu m’envoyer un mail ?

    Merci

  2. Merci pour cet article.
    J’aurais une question.
    Je souhaiterais faire une réplication d’un memcached maitre vers X autres memcached.
    Est ce envisageable avec repcached ?
    Merci

  3. « Parmi ses fonctionnalités :

    * multi master replication. »

    Potentiellement la réponse est donc oui mais pas tester.

  4. Fiabilité ?
    Compatibilité avec php5-memcache de lenny (module pecl en 3.0.1) ?

    J’hésite un peu entre cette solution et mysql (déjà répliqué en master-master par ailleurs)…

    Je cherche plus la fiabilité (sessions préservées en cas de failover, et sessions qui tombent pas en rade) que les perfs et mysql semble plus indiqué pour ça (si il tombe malgré le failover auto, j’ai plus de site), avec une table en mémoire probablement.

    Mais cette solution est plus simple à mettre en œuvre (pas de classe d’accès aux sessions à insérer dans chaque projet, juste de la conf php), donc j’hésite encore, tout conseil ou retour d’usage en prod sera bienvenu…

  5. La fiabilité des réplicats memcached est depuis longtemps assurée.
    Je ne vois par le rapport avec les modules php5/pecl ??? qu’on écrive sur 1 ou 30 memcached, c’est pareil.
    Memcached n’est pas fait pour remplacer mysql, c’est un systeme de cache clé/valeur, pas une BDD relationnelle/transactionnelle.