Un pool de démons memcache peut-il être utilisé pour partager des sessions plus efficacement?

25

Nous passons d'une configuration à un serveur Web à une configuration à deux serveurs Web et je dois commencer à partager des sessions PHP entre les deux machines à charge équilibrée. Nous avons déjà installé ( et commencé ) memcached et j'ai donc été agréablement surpris de pouvoir partager des sessions entre les nouveaux serveurs en changeant seulement 3 lignes dans le fichier ( session.save_handler et session.save_path ):php.ini

J'ai remplacé:

session.save_handler = files

avec:

session.save_handler = memcache

Ensuite, sur le serveur Web principal, j'ai défini le session.save_pathpointeur sur localhost:

session.save_path="tcp://localhost:11211"

et sur le serveur Web esclave, je mets le session.save_pathpointeur vers le maître:

session.save_path="tcp://192.168.0.1:11211"

Travail fait, je l'ai testé et ça marche. Mais...

Évidemment, utiliser memcache signifie que les sessions sont en RAM et seront perdues si une machine est redémarrée ou si le démon memcache se bloque - cela m'inquiète un peu, mais je suis un peu plus inquiet pour le trafic réseau entre les deux serveurs Web (surtout que nous évoluons) car chaque fois que quelqu'un est équilibré en charge sur le serveur Web esclave, ses sessions sont récupérées sur le réseau depuis le serveur Web maître. Je me demandais si je pouvais en définir deux save_pathspour que les machines regardent dans leur propre stockage de session avant d'utiliser le réseau. Par exemple:

Maîtriser:

session.save_path="tcp://localhost:11211, tcp://192.168.0.2:11211"

Esclave:

session.save_path="tcp://localhost:11211, tcp://192.168.0.1:11211"

Est-ce que cela partagerait avec succès des sessions sur les serveurs ET aiderait les performances? c'est à dire économiser du trafic réseau 50% du temps. Ou cette technique est-elle uniquement destinée aux basculements (par exemple, lorsqu'un démon memcache est inaccessible)?

Remarque : je ne pose pas vraiment de question sur la réplication de memcache - plus sur si le client PHP memcache peut atteindre son pic à l'intérieur de chaque démon memcache dans un pool, retourner une session s'il en trouve une et créer seulement une nouvelle session s'il n'en trouve pas une dans tous les magasins. Alors que j'écris ceci, je pense que je demande un peu trop à PHP, lol ...

Supposons : pas de sessions persistantes, équilibrage de charge à tour de rôle, serveurs LAMP.

À M
la source
1
La documentation de Memcache ne recommande pas d'utiliser Memcache pour le stockage de session. Voir code.google.com/p/memcached/wiki/… !

Réponses:

37

Avertissement: vous seriez fou de m'écouter sans faire une tonne de tests ET obtenir une 2e opinion de quelqu'un de qualifié - je suis nouveau dans ce jeu .

L'idée d'amélioration de l'efficacité proposée dans cette question ne fonctionnera pas. La principale erreur que j'ai commise a été de penser que l'ordre de définition des magasins memcached dans le pool dicte une sorte de priorité. Ce n'est pas le cas . Lorsque vous définissez un pool de démons mis en mémoire (par exemple en utilisant session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"), vous ne pouvez pas savoir quel magasin sera utilisé. Les données sont réparties uniformément, ce qui signifie qu'un élément peut être stocké dans le premier, ou ce peut être le dernier (ou les deux si le client memcache est configuré pour se répliquer - notez que c'est le client qui gère la réplication, le serveur memcached le fait pas le faire lui-même). Dans les deux cas, l'utilisation de localhost comme premier du pool n'améliorera pas les performances - il y a 50% de chances de toucher l'un ou l'autre magasin.

Après avoir fait un peu de tests et de recherches, j'ai conclu que vous POUVEZ partager des sessions sur plusieurs serveurs en utilisant memcache MAIS vous ne le voulez probablement pas - cela ne semble pas être populaire car il ne s'adapte pas aussi bien que l'utilisation d'un partage base de données à elle n'est pas aussi robuste. J'apprécierais vos commentaires à ce sujet afin que je puisse en savoir plus ...

Ignorez les éléments suivants, sauf si vous avez une application PHP:


Astuce 1: Si vous souhaitez partager des sessions sur 2 serveurs à l'aide de memcache:

Assurez-vous d'avoir répondu Oui à « Activer la prise en charge du gestionnaire de sessions memcache? » Lorsque vous avez installé le client PHP memcache et ajoutez ce qui suit dans votre /etc/php.d/memcache.inifichier:

session.save_handler = memcache

Sur le serveur Web 1 (IP: 192.168.0.1):

session.save_path="tcp://192.168.0.1:11211"

Sur le serveur Web 2 (IP: 192.168.0.2):

session.save_path="tcp://192.168.0.1:11211"

Astuce 2: Si vous souhaitez partager des sessions sur 2 serveurs à l'aide de memcache ET prendre en charge le basculement:

Ajoutez les éléments suivants à votre /etc/php.d/memcache.inifichier:

memcache.hash_strategy = consistent
memcache.allow_failover = 1

Sur le serveur Web 1 (IP: 192.168.0.1):

session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"

Sur le serveur Web 2 (IP: 192.168.0.2):

session.save_path="tcp://192.168.0.1:11211, tcp://192.168.0.2:11211"

Remarques:

  • Cela met en évidence une autre erreur que j'ai faite dans la question d'origine - je n'utilisais pas un identifiant identique session.save_pathsur tous les serveurs.
  • Dans ce cas, "basculement" signifie qu'en cas de défaillance d'un démon memcache, le client PHP memcache commencera à utiliser l'autre. c'est-à-dire que toute personne dont la session dans le magasin a échoué sera déconnectée. Ce n'est pas un basculement transparent.

Astuce 3: Si vous souhaitez partager des sessions à l'aide de memcache ET avoir un support de basculement transparent:

Identique à l'astuce 2, sauf que vous devez ajouter ce qui suit à votre /etc/php.d/memcache.inifichier:

memcache.session_redundancy=2

Remarques:

  • Cela fait que le client PHP memcache écrit les sessions sur 2 serveurs. Vous obtenez une redondance (comme RAID-1) afin que les écritures soient envoyées à n miroirs et que les échecs get'ssoient réessayés sur les miroirs. Cela signifie que les utilisateurs ne perdent pas leur session en cas de défaillance d'un démon memcache.
  • Les écritures en miroir sont effectuées en parallèle (en utilisant des E / S non bloquantes) de sorte que les performances de vitesse ne devraient pas baisser autant que le nombre de miroirs augmente. Cependant, le trafic réseau augmentera si vos miroirs memcache sont distribués sur différentes machines. Par exemple, il n'y a plus 50% de chances d'utiliser localhost et d'éviter l'accès au réseau.
    • Apparemment, le retard dans la réplication d'écriture peut entraîner la récupération d'anciennes données au lieu d'un échec de cache. La question est de savoir si cela est important pour votre candidature? À quelle fréquence écrivez-vous des données de session?
  • memcache.session_redundancyest pour la redondance de session mais il y a aussi une memcache.redundancyoption ini qui peut être utilisée par votre code d'application PHP si vous voulez qu'il ait un niveau de redondance différent.
  • Vous avez besoin d'une version récente (toujours en version bêta pour le moment) du client PHP memcache - la version 3.0.3 de pecl a fonctionné pour moi.
À M
la source
Pourriez-vous commenter sur "il ne évolue pas aussi bien que l'utilisation d'une base de données partagée"? Je ne vois pas en quoi il est différent d'une configuration DB maître-esclave typique. Merci!
Boy Baukema
C'est une ventilation assez cool, bien qu'il y ait des rumeurs (alias rapports de bogues) que cela ne fonctionne pas comme prévu lorsque vous utilisez la ext/memcacheversion 3.x. Nous jouons également avec cette option et j'ai décidé de parcourir la liste des serveurs et d'y écrire moi-même.
jusqu'au
dans le cas de l'astuce 3: que se passe-t-il si un hôte memcached tombe en panne et qu'il revient, puis que l'hôte en secondes descend. si je comprends bien - aucune donnée de session ne sera restaurée et une partie sera perdue, non?
GioMac
28

Re: Astuce 3 ci-dessus (pour toute autre personne rencontrant cela via google), il semble qu'au moins actuellement pour que cela fonctionne, vous devez utiliser memcache.session_redundancy = N+1pour N serveurs dans votre pool , au moins cela semble être le seuil minimum valeur qui fonctionne. (Testé avec php 5.3.3 sur debian stable, pecl memcache 3.0.6, deux serveurs memcached. Échoueraient dès que j'éteindrais session_redundancy=2le premier serveur dans le save_path, session_redundancy=3fonctionne très bien.)

Cela semble être capturé dans ces rapports de bogues:

Michael Jackson
la source
1
Je ne peux pas vous voter assez ..
fest
1
Je suis content d'avoir fait défiler la page. C'était ça le problème.
Daren Schwenke
Ce n'est pas clair pour moi, cette fonctionnalité est-elle uniquement disponible dans la série PECL memcache 3.x? Tous ceux-ci sont répertoriés sur le logiciel Beta sur pecl.php.net/package/memcache , alors que sur 2.2.7 si je tue le serveur sur lequel je vois le leader, tout meurt.
Joe
Cela fait des années que je n'ai pas regardé ça, pour être honnête. Si je me souviens bien, c'était une fonctionnalité 3.x (icbw). Nous avons déployé de nombreux systèmes utilisant les versions "bêta" de ce plugin (certains d'entre eux un trafic assez élevé) et nous n'avons eu aucun problème qui semblait lié à cela. YMMV, testez les choses avant qu'elles ne soient mises en ligne, etc. :) Je ne travaille pas en PHP depuis quelques années maintenant, donc certains des points les plus délicats commencent à s'estomper.
Michael Jackson
3

Avec les paramètres php.ini indiqués ci-dessus, assurez-vous que les paramètres suivants sont également définis:

memcache.allow_failover = 1  
memcache.hash_strategy = 'consistent'

Vous obtiendrez alors un basculement complet et une redondance côté client. La mise en garde avec cette approche est que si memcached est en panne sur localhost, il y aura toujours un échec de lecture avant que le client php memcache n'essaye le serveur suivant dans le pool spécifié dans session.save_path

Gardez à l'esprit que cela affecte les paramètres globaux du client php memcache exécuté sur votre serveur Web.

Ian Lewis
la source
Est-il consistentjudicieux d' utiliser une stratégie de hachage étant donné que le session.save_pathest différent sur chaque serveur Web?
Tom
1

memcached ne fonctionne pas de cette façon (veuillez me corriger si je me trompe!)

Si vous souhaitez que votre application dispose d'un stockage de session redondant, vous devez créer quelque chose qui modifie / ajoute / supprime des entrées pour les deux instances memcached. memcached ne gère pas cela, la seule chose qu'il fournit est un stockage de hachage de clé. Donc pas de réplication, de synchronisation, rien, nada.

J'espère que je ne me trompe pas sur cette question, mais c'est ce que je sais de memcached, cela fait quelques années que je l'ai touché.

déchiré
la source
Ce serait pratique pour moi si vous vous trompiez. :-) Il y a un article sur phpslacker.com ( phpslacker.com/2009/03/02/php-session-clustering-with-memcache ) qui suggère que memcached peut fonctionner comme décrit dans la question. Cela dépend peut-être de la façon dont le client memcache implémente la stratégie de hachage?
Tom
1
memcache ne fonctionne pas comme ça, mais il semble que php puisse fonctionner comme vous le souhaitez. Vous devrez changer php.ini ou changer votre application comme décrit. Du blog: Où est le regroupement que vous demandez Eh bien, à vrai dire, il n'y en a pas. Ce que nous avons jusqu'à présent est un pool memcache composé de 2 serveurs. PHP est configuré pour écrire dans le pool. PHP lit / écrit dans le pool de serveurs dans l'ordre spécifié par la directive ini «session.save_path». Pour les lectures, PHP demandera un objet de cache par clé au pool. Parce que le «basculement» est activé, PHP interrogera le pool de serveurs memcache un par un jusqu'au [...]
déchu
1

memcached ne se réplique pas hors de la boîte, mais repcached (un memcached patché) le fait. Cependant, si vous utilisez déjà mysql, pourquoi ne pas simplement utiliser sa fonctionnalité de réplication avec la réplication maître-maître et bénéficier de la réplication complète des données.

C.

symcbean
la source
Merci pour l'info. Ce n'est pas vraiment la réplication que je recherche. Il s'agit plutôt de vouloir faire un tour dans chaque memcached jusqu'à ce que la session soit trouvée. c'est-à-dire vérifier d'abord localhost parce qu'il est le plus rapide et ensuite vérifier l'autre serveur.
Tom
1
Au nom de tous les dieux POURQUOI ???? C'est la mauvaise solution pour ... enfin à peu près n'importe quel problème auquel je peux penser. En plus d'être très inefficace même avec seulement 2 serveurs, les performances empireront très rapidement très rapidement si vous ajoutez des serveurs. Et cela ne tient pas compte du fait que votre solution rend les pannes deux fois plus probables qu'elles ne l'étaient avec un seul serveur alors qu'en pratique, l'ajout de serveurs à un cluster devrait réduire la probabilité d'une panne. (BTW si vous voulez dire un round-robin basé sur DNS, alors l'affinité de session est implicite!)
symcbean
Merci pour les commentaires, oui, j'admets librement que je suis un noob au partage de session! :-) Cependant, je n'ai toujours pas compris pourquoi ma proposition est si moche. Je pensais que ce serait plus efficace que d'utiliser une base de données partagée et je pensais également que cela rendrait les pannes moins probables.
Tom
Non, cela les rend plus probables. La fédération des données comme celle-ci est logique lorsque vous avez un très grand nombre de nœuds, car vous réduisez la quantité de réplication, mais on ferait généralement une réplication avec un nombre défini de pools pour préserver la disponibilité. Vous devez être très pointilleux sur les performances pour voir une différence entre la réplication repcached et la réplication mysqld.
symcbean
J'ai testé et confirmé que tant que j'utilise allow_failover = 1, plusieurs miroirs rendent les pannes MOINS probables. Je peux éteindre un miroir, le redémarrer et éteindre l'autre, le redémarrer et éteindre le premier à nouveau - le tout sans être déconnecté. Je suppose que le client PHP memcache fait beaucoup de ruse en coulisses.
Tom