Le socket mal équilibré accepte le kernel Linux 3.2 vs le kernel 2.6

J’exécute une application Node.js 0.8.8 à grande échelle utilisant Cluster avec 16 processus de travail sur une boîte de 16 processeurs avec hyperthreading (32 cœurs logiques). Nous constatons que depuis le passage au kernel Linux 3.2.0 (à partir de la version 2.6.32), l’équilibrage des requêtes entrantes entre les processus enfants de travail semble peser à peu près 5 processus, les 11 autres ne faisant pas beaucoup de travail. Cela peut être plus efficace pour le débit, mais semble augmenter la latence des requêtes et n’est pas optimal pour nous, car nombre d’entre eux sont des connexions de socket Web à long terme qui peuvent commencer à fonctionner simultanément.

Les processus enfants acceptent tous sur un socket (en utilisant epoll), et bien que ce problème ait un correctif dans le nœud 0.9 (https://github.com/bnoordhuis/libuv/commit/be2a2176ce25d6a4190b10acd1de9fd53f7a6275), cette correction ne semble pas aider nos tests Quelqu’un a-t-il connaissance des parameters d’optimisation du kernel ou des options de génération qui pourraient aider, ou est-il préférable de revenir au kernel 2.6 ou à l’équilibrage de la charge entre les processus de travail en utilisant une approche différente?

Nous l’avons réduit à un simple test HTTP Siege, mais notez que cela fonctionne avec 12 processus sur une boîte de 12 cœurs avec hyperthreading (24 cœurs logiques) et que 12 processus de travail acceptent le socket, par opposition à nos 16 processus. procs en production.

HTTP Siege avec Node 0.9.3 sur Debian Squeeze avec le kernel 2.6.32 sur bare metal:

reqs pid 146 2818 139 2820 211 2821 306 2823 129 2825 166 2827 138 2829 134 2831 227 2833 134 2835 129 2837 138 2838 

Même chose avec le kernel 3.2.0:

 reqs pid 99 3207 186 3209 42 3210 131 3212 34 3214 53 3216 39 3218 54 3220 33 3222 931 3224 345 3226 312 3228 

Ne dépendez pas de la prise multiple du socket du système d’exploitation pour équilibrer la charge entre les processus du serveur Web.

Le comportement des kernelx Linux diffère ici d’une version à l’autre, et nous avons constaté un comportement particulièrement déséquilibré avec le kernel 3.2, qui semblait être un peu plus équilibré dans les versions ultérieures. par exemple 3.6.

Nous travaillions sous l’hypothèse qu’il devrait y avoir un moyen de faire en sorte que Linux fasse quelque chose comme round-robin avec ceci, mais il y avait une variété de problèmes avec ceci, y compris:

  • Le kernel Linux 2.6 a montré quelque chose comme un comportement de round-robin sur le bare metal (les déséquilibres étaient d’environ 3 pour 1), le kernel Linux 3.2 (déséquilibres 10 à 1) et le kernel 3.6.10 semblait à nouveau correct. Nous n’avons pas tenté de couper en deux vers le changement réel.
  • Indépendamment de la version du kernel ou des options de génération utilisées, le comportement que nous avons observé sur une instance HVM à cœur logique 32 sur les services Amazon Web était fortement lié à un processus unique; il peut y avoir des problèmes avec le socket Xen accepter: https://serverfault.com/questions/272483/why-is-tcp-accept-performance-so-bad-under-xen

Vous pouvez voir nos tests en détail sur le problème de github que nous utilisions pour correspondre avec l’excellente équipe Node.js, en commençant par ici: https://github.com/joyent/node/issues/3241#issuecomment-11145233

Cette conversation se termine avec l’équipe Node.js indiquant qu’ils envisagent sérieusement d’implémenter un round-robin explicite dans le cluster, et de lancer un problème pour cela: https://github.com/joyent/node/issues/4435 , et avec le Trello équipe (qui est nous) allant à notre plan de secours, qui consistait à utiliser un processus HAProxy local pour proxy sur 16 ports sur chaque machine serveur, avec une instance de cluster à 2 processus exécutée sur chaque port (pour un basculement rapide au niveau accepté) en cas de plantage ou de blocage du processus). Ce plan fonctionne à merveille, avec une variation considérablement réduite de la latence des requêtes et une latence moyenne inférieure.

Il y a beaucoup à dire ici, et je n’ai PAS pris la décision de poster la liste de diffusion du kernel Linux, car il n’était pas clair s’il s’agissait vraiment d’un problème de kernel Xen ou Linux, ou simplement d’une attente incorrecte. comportement de notre part.

J’adorerais voir une réponse d’un expert sur l’acceptation multiple, mais nous revenons à ce que nous pouvons construire en utilisant des composants que nous comprenons mieux. Si quelqu’un publie une meilleure réponse, je serais ravi de l’accepter au lieu de la mienne.