Des centaines/milliers de sockets TCP sont-ils raisonnables avec Memcached ?
-
21-08-2019 - |
Question
J'utilise Merb::Cache pour stocker txt/xml et j'ai remarqué que plus je laisse mes merbs fonctionner longtemps, plus le nombre de sockets TCP ouverts que j'ai ouverts est important - je pense que cela provoque des problèmes de performances majeurs.
lsof | grep 11211 | wc -l 494
merb 27206 root 71u IPv4 13759908 TCP localhost.localdomain:59756->localhost.localdomain:11211 (ESTABLISHED) merb 27206 root 72u IPv4 13759969 TCP localhost.localdomain:59779->localhost.localdomain:11211 (ESTABLISHED) merb 27206 root 73u IPv4 13760039 TCP localhost.localdomain:59805->localhost.localdomain:11211 (ESTABLISHED) merb 27206 root 74u IPv4 13760052 TCP localhost.localdomain:59810->localhost.localdomain:11211 (ESTABLISHED) merb 27206 root 75u IPv4 13760135 TCP localhost.localdomain:59841->localhost.localdomain:11211 (ESTABLISHED) merb 27206 root 76u IPv4 13760823 TCP localhost.localdomain:59866->localhost.localdomain:11211 (ESTABLISHED) merb 27206 root 77u IPv4 13760951 TCP localhost.localdomain:52095->localhost.localdomain:11211 (ESTABLISHED)
etc...
mon code pertinent est :
if !exists?(:memcached) then register(:memcached, Merb::Cache::MemcachedStore, :namespace => 'mynamespace', :servers => ['127.0.0.1:11211']) end
&&
when :xml unless @hand_xml = Merb::Cache[:memcached].read("/hands/#{@hand.id}.xml") @hand_xml = display(@hand) Merb::Cache[:memcached].write("/hands/#{@hand.id}.xml", @hand_xml) end return @hand_xml
ce code est-il carrément faux ou est-ce que j'utilise la mauvaise version de memcache ??
J'ai Memcached 1.2.8 et j'ai ce qui suit:
libmemcached-0.25.14.tar.gz memcached-0.13.gem
ça me rend un peu fou..
La solution
k J'ai découvert des trucs..
1) il PEUT être raisonnable d'avoir des centaines/milliers de sockets connectés à memcached en supposant que vous utilisez une bibliothèque qui utilise epoll ou autre chose - cependant, si vous utilisez Ruby comme moi, je ne connais pas de bibliothèque qui utilise quelque chose autre que select() ou poll() -- donc cela pose cette question/veut sortir immédiatement
2) si vous êtes comme moi, vous n'avez qu'un seul serveur Memcache en cours d'exécution en ce moment et quelques bâtards/minces qui s'occupent des requêtes... par conséquent, vos connexions Memcache devraient être problématiques.ne soyez pas supérieur au nombre de bâtards/minces que vous exécutez (en supposant que vous ne mettiez en cache qu'un ou deux ensembles de choses) - ce qui était mon cas
voici le correctif :
configurer Memcache via Memcached Gem plutôt que merb::cache (qui enveloppe en fait la bibliothèque Memcache que vous utilisez
MMCACHE = Memcached.new("localhost:11211")
obtenez/définissez vos valeurs :
@cache = MMCACHE.clone
begin
@hand_xml = @cache.get("/hands/#{@hand.id}.xml")
rescue
@hand_xml = display(@hand)
@cache.set("/hands/#{@hand.id}.xml", @hand_xml)
end
@cache.quit
asseyez-vous et buvez-en un froid parce que maintenant, quand vous faites ça :
lsof | grep 11211 | wc -l
vous voyez quelque chose comme 2 ou 3 au lieu de 2036 !
merci à Reef de m'avoir indiqué qu'il n'est pas rare que les connexions Memcache soient persistantes au début
Autres conseils
Je pourrais être en mesure d'aider, mais je dois raconter une histoire à faire. Ici, il est.
Il était une fois il y avait un groupe de 10 serveurs Apache (SSL) configuré pour avoir exactement 100 fils chacun. Il y avait aussi un groupe de 10 serveurs memcached (sur les mêmes boîtes), et ils ont tous semblait vivre en paix. Les deux ont été gardés par le mal démon Monit et les années memcached apache.
Le roi installé un serveur apache 11 (ssl) et ont commencé à memcached de redémarrer au hasard quelques heures! Le roi a commencé à enquêter et qu'at-il trouvé? Il y avait un bug dans la documentation du module PHP memcache qui a dit que le constructeur par défaut de l'objet de connexion memcache est pas persistante, mais apparemment il était. Ce qui est arrivé est que chaque thread php (et il y avait comme 1000 d'entre eux), a ouvert une connexion à chaque memcached dans la piscine quand il avait besoin d'un, et il le tenait. Il y avait 10 * 100 connexions à chaque serveur memcached et il était très bien, mais avec 11 serveurs, il était 1100 et que 1024 <1100. Nombre maximum de sockets ouvertes pour memcached était 1024. Lorsque toutes les prises ont été prises, le démon Monit ne pouvait pas se connecter, donc il a relancé le memcached.
Chaque histoire doit avoir une morale. Alors, qu'est-ce que fait le roi avec tout cela? Il désactivé les connexions persistantes et ils heureusement jamais après tout vécu, avec le nombre de connexions sur le pic de cluster à 5 (cinq). Ces serveurs purgeaient quantité de tamiser des données, donc on ne pouvait pas 1000 et prises de rechange était moins cher de négocier la connexion memcache à chaque demande.
Je suis désolé, mais je ne sais pas Ruby, il semble que vous aviez une quantité terrible de fils ou vous êtes mise en cache mal.
Bonne chance!