La vitesse à laquelle mon serveur peut accepter() de nouvelles connexions TCP entrantes est vraiment mauvaise sous Xen. Le même test sur du matériel bare metal montre des vitesses de 3 à 5 fois supérieures.
- Comment se fait-il que ce soit si mauvais sous Xen ?
- Pouvez-vous modifier Xen pour améliorer les performances des nouvelles connexions TCP ?
- Existe-t-il d'autres plateformes de virtualisation mieux adaptées à ce type de cas d'utilisation ?
Contexte
Dernièrement, j'ai fait des recherches sur certains goulots d'étranglement au niveau des performances d'un serveur Java développé en interne et fonctionnant sous Xen. Le serveur utilise HTTP et répond à des appels TCP simples de type connexion/réponse/déconnexion.
Mais même en envoyant des tonnes de trafic au serveur, celui-ci ne peut accepter plus de 7000 connexions TCP par seconde (sur une instance EC2 à 8 cœurs, c1.xlarge exécutant Xen). Pendant le test, le serveur a également montré un comportement étrange où un cœur (pas nécessairement le cpu 0) est très chargé >80%, tandis que les autres cœurs restent presque inactifs. Cela m'amène à penser que le problème est lié au noyau/à la virtualisation sous-jacente.
Lorsque je teste le même scénario sur une plate-forme non virtualisée, j'obtiens des résultats de test montrant des taux TCP accept() supérieurs à 35 000/seconde. Ceci sur une machine Core i5 4 cœurs exécutant Ubuntu avec tous les cœurs presque entièrement saturés. Pour moi, ce genre de chiffre me semble correct.
Sur l'instance Xen à nouveau, j'ai essayé d'activer/de modifier presque tous les paramètres disponibles dans sysctl.conf. Y compris l'activation de Réception de paquets de direction y Orientation du flux de réception et l'affectation de threads/processus aux CPU, mais sans gain apparent.
Je sais qu'il faut s'attendre à une dégradation des performances en cas de fonctionnement virtuel. Mais à ce point ? Un serveur bare metal plus lent surpasse virt. 8-core par un facteur de 5 ?
- Est-ce vraiment le comportement attendu de Xen ?
- Pouvez-vous modifier Xen pour améliorer les performances des nouvelles connexions TCP ?
- Existe-t-il d'autres plateformes de virtualisation mieux adaptées à ce type de cas d'utilisation ?
Reproduire ce comportement
En approfondissant l'enquête et en localisant le problème, j'ai découvert que le netperf Un outil de test de performance pourrait simuler le scénario similaire que je rencontre. À l'aide du test TCP_CRR de Netperf, j'ai collecté plusieurs rapports provenant de différents serveurs (virtualisés ou non). Si vous souhaitez contribuer avec des résultats ou consulter mes rapports actuels, veuillez vous rendre sur le site suivant https://gist.github.com/985475
Comment puis-je savoir que ce problème n'est pas dû à un logiciel mal écrit ?
- Le serveur a été testé sur du matériel bare metal et il sature presque tous les cœurs dont il dispose.
- En utilisant des connexions TCP keep-alive, le problème disparaît.
Pourquoi est-ce important ?
Sur ESN (mon employeur) Je suis le chef de projet de Beaconpush un serveur Comet/Web Socket écrit en Java. Bien qu'il soit très performant et qu'il puisse saturer presque toute la bande passante qui lui est donnée dans des conditions optimales, il est toujours limité à la vitesse à laquelle de nouvelles connexions TCP peuvent être établies. En d'autres termes, si vous avez un grand nombre d'utilisateurs qui vont et viennent très souvent, de nombreuses connexions TCP devront être établies ou supprimées. Nous essayons d'atténuer ce phénomène en maintenant les connexions en vie aussi longtemps que possible. Mais au final, les performances de la fonction accept() empêchent nos cœurs de tourner et nous n'aimons pas cela.
Mise à jour 1
Quelqu'un a posté cette question à Hacker News il y a aussi des questions/réponses. Mais je vais essayer de garder cette question à jour avec les informations que je trouve au fur et à mesure.
Matériel/plateformes sur lesquels j'ai testé ce produit :
- EC2 avec les types d'instance c1.xlarge (8 cœurs, 7 GB RAM) et cc1.4xlarge (2x Intel Xeon X5570, 23 GB RAM). Les AMIs utilisés sont respectivement ami-08f40561 et ami-1cad5275. Quelqu'un a également fait remarquer que les "groupes de sécurité" (c'est-à-dire le pare-feu de l'EC2) pourraient également avoir une incidence. Mais pour ce scénario de test, j'ai essayé uniquement sur localhost pour éliminer les facteurs externes tels que celui-ci. Une autre rumeur que j'ai entendue est que les instances EC2 ne peuvent pas pousser plus de 100k PPS.
- Deux serveurs privés virtualisés fonctionnant sous Xen. L'un d'eux n'avait aucune charge avant le test, mais cela n'a pas fait de différence.
- Dédié privé, serveur Xen chez Rackspace. A peu près les mêmes résultats.
Je suis en train de refaire ces tests et de remplir les rapports à l'adresse suivante https://gist.github.com/985475 Si vous voulez aider, contribuez par vos chiffres. C'est facile !
(Le plan d'action a été déplacé vers une réponse séparée et consolidée).
3 votes
Excellent travail de localisation d'un problème, mais je pense que vous seriez bien mieux servi sur une liste de diffusion spécifique à Xen, un forum de support ou même le Site de rapport de bogues de xensource . Je pense qu'il pourrait s'agir d'un bug de l'ordonnanceur - si vous prenez vos chiffres de 7 000 connexions * 4 cœurs / 0,80 charge CPU, vous obtenez exactement 35 000 - le nombre que vous obtiendriez lorsque 4 cœurs seraient entièrement saturés.
0 votes
Ah, et encore une chose : essayez une version différente (plus récente peut-être) du noyau pour votre invité, si vous le pouvez.
0 votes
@syneticon-dj Merci. Je l'ai essayé sur un cc1.4xlarge sur EC2 avec le noyau 2.6.38. J'ai vu une augmentation d'environ ~10% si je ne me trompe pas. Mais c'est plus probablement dû au matériel plus musclé de ce type d'instance.
6 votes
Merci d'avoir mis à jour ce dossier avec les réponses de HN, c'est une excellente question. Je suggère de déplacer le plan d'action dans une réponse consolidée, éventuellement - car ce sont toutes des réponses possibles au problème.
0 votes
@jeff Déplacez le plan d'action, vérifiez.