89 votes

Pourquoi les performances de TCP accept() sont-elles si mauvaises sous Xen ?

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.

  1. Comment se fait-il que ce soit si mauvais sous Xen ?
  2. Pouvez-vous modifier Xen pour améliorer les performances des nouvelles connexions TCP ?
  3. 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 ?

  1. Est-ce vraiment le comportement attendu de Xen ?
  2. Pouvez-vous modifier Xen pour améliorer les performances des nouvelles connexions TCP ?
  3. 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 ?

  1. Le serveur a été testé sur du matériel bare metal et il sature presque tous les cœurs dont il dispose.
  2. 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.

27voto

Jonathan Hanson Points 628

En ce moment même : La performance des petits paquets craint sous Xen

(déplacé de la question elle-même vers une réponse séparée à la place)

Selon un utilisateur de HN (un développeur de KVM ?), cela est dû aux performances des petits paquets dans Xen et aussi dans KVM. C'est un problème connu de la virtualisation et, selon lui, ESX de VMWare gère bien mieux ce problème. Il a également noté que KVM apporte de nouvelles fonctionnalités destinées à atténuer ce problème ( poste original ).

Cette information est un peu décourageante si elle est correcte. Quoi qu'il en soit, je vais essayer les étapes ci-dessous jusqu'à ce qu'un gourou de Xen vienne avec une réponse définitive :)

Iain Kay de la liste de diffusion xen-users a compilé ce graphique : netperf graph Remarquez les barres TCP_CRR, comparez "2.6.18-239.9.1.el5" à "2.6.39 (avec Xen 4.1.0)".

Plan d'action actuel basé sur les réponses/réponses ici et auprès de HN :

  1. Soumettre ce problème à une liste de diffusion spécifique à Xen et au bugzilla de xensource comme suggéré par syneticon-dj. A le message a été posté sur la liste xen-user en attendant une réponse.

  2. Créez un cas de test pathologique simple, au niveau de l'application, et publiez-le.
    Un serveur de test avec des instructions a été créé et publié sur GitHub . Avec cela, vous devriez être en mesure de voir un cas d'utilisation plus réel par rapport à netperf.

  3. Essayez une instance d'invité Xen PV 32 bits, car le 64 bits pourrait causer plus de surcharge dans Xen. Quelqu'un l'a mentionné sur HN. Ça n'a pas fait de différence.

  4. Essayez d'activer net.ipv4.tcp_syncookies dans sysctl.conf comme suggéré par abofh sur HN. Cela semble pourrait améliorer les performances puisque la poignée de main se produirait dans le noyau. Je n'ai pas eu de chance avec ça.

  5. Augmenter l'arriéré de 1024 à quelque chose de beaucoup plus élevé, également suggéré par abofh sur HN. Cela pourrait également aider puisque l'invité pourrait potentiellement accepter() plus de connexions pendant sa tranche d'exécution donnée par dom0 (l'hôte).

  6. Vérifiez que conntrack est désactivé sur toutes les machines car il peut réduire de moitié le taux d'acceptation (suggéré par deubeulyou). Oui, il a été désactivé dans tous les tests.

  7. Vérifier si "listen queue overflow and syncache buckets overflow in netstat -s" (suggéré par mike_esspe sur HN).

  8. Répartir la gestion des interruptions entre plusieurs cœurs (les RPS/RFS que j'ai essayé d'activer plus tôt sont censés faire cela, mais il pourrait être utile de réessayer). Proposé par adamt à HN.

  9. Désactiver le déchargement de la segmentation TCP et l'accélération de la diffusion/récolte comme suggéré par Matt Bailey. (Impossible sur EC2 ou les hôtes VPS similaires)

2 votes

+1 Postez définitivement les résultats de la performance lorsque vous l'aurez découvert !

0 votes

Quelqu'un m'a interpellé sur Twitter à propos de cette question. Malheureusement, il semble que ce problème persiste. Je n'ai pas fait beaucoup de recherches depuis l'année dernière. Xen PEUT s'être amélioré pendant ce temps, je ne sais pas. Le développeur de KVM a également mentionné qu'ils s'attaquaient à des problèmes comme celui-ci. Cela pourrait valoir la peine de poursuivre. En outre, une autre recommandation que j'ai entendue est d'essayer OpenVZ au lieu de Xen/KVM car il ajoute moins ou pas de couches/interception des appels système.

23voto

Matt Jacob Points 26

Anecdotiquement, j'ai constaté que la désactivation de l'accélération matérielle des cartes d'interface réseau améliore considérablement les performances du réseau sur le contrôleur Xen (également vrai pour LXC) :

Accellulaire dispersé :

/usr/sbin/ethtool -K br0 sg off

Déchargement de la segmentation TCP :

/usr/sbin/ethtool -K br0 tso off

Où br0 est votre pont ou périphérique réseau sur l'hôte de l'hyperviseur. Vous devrez le configurer pour le désactiver à chaque démarrage. YMMV.

0 votes

Je suis d'accord avec ça. J'avais un serveur Windows 2003 fonctionnant sous Xen qui souffrait d'horribles problèmes de perte de paquets dans des conditions de haut débit. Le problème a disparu lorsque j'ai désactivé le déchargement des segments TCP.

0 votes

Merci. J'ai mis à jour le "plan d'action" dans la question originale avec vos suggestions.

0 votes

3voto

deubeulyou Points 131

Peut-être pourriez-vous clarifier un peu - avez-vous exécuté les tests sous Xen sur votre propre serveur, ou seulement sur une instance EC2 ?

Accept est juste un autre appel système, et les nouvelles connexions ne sont différentes que par le fait que les premiers paquets auront des drapeaux spécifiques - un hyperviseur tel que Xen ne devrait certainement pas voir de différence. D'autres parties de votre configuration peuvent faire la différence : dans EC2 par exemple, je ne serais pas surpris que les groupes de sécurité aient quelque chose à voir avec cela ; conntrack est également un outil de gestion de la sécurité. rapporté pour réduire de moitié le taux d'acceptation des nouvelles connexions (PDF) .

Enfin, il semble qu'il y ait des combinaisons CPU/Noyau qui provoquent une utilisation bizarre du CPU / des blocages sur EC2 (et probablement Xen en général), comme par exemple récemment évoqué par Librato sur son blog .

0 votes

J'ai mis à jour la question et précisé sur quel matériel j'ai essayé. abofh a également suggéré d'augmenter le backlog au-delà de 1024 pour accélérer le nombre d'accept()s possibles pendant une tranche d'exécution pour l'invité. En ce qui concerne conntrack, je devrais certainement vérifier que ces choses sont désactivées, merci. J'ai lu l'article de Liberato, mais étant donné le nombre de matériels différents sur lesquels j'ai essayé, cela ne devrait pas être le cas.

0 votes

Une chose à laquelle il faut faire attention est que sous PVM Xen, les chiffres de charge des invités ne disent que la moitié de la vérité : en général, il faut aussi surveiller les chiffres de charge de l'hyperviseur. Plus précisément, il faut surveiller le (assez récemment (depuis Linux 2.6.11)) "steal rate" (champ 8 dans /proc/stat ) dans l'invité peut être intéressant.

0voto

wolfg Points 51

Assurez-vous d'avoir désactivé iptables et autres hooks dans le code de pontage du dom0. Évidemment, cela ne s'applique qu'à la configuration Xen de la mise en réseau par pont.

echo 0 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 0 > /proc/sys/net/bridge.bridge-nf-call-arptables

Cela dépend de la taille du serveur, mais pour les plus petits (processeur à 4 cœurs), il faut dédier un cœur de processeur à Xen dom0 et l'épingler. Options de démarrage de l'hyperviseur :

dom0_max_vcpus=1 dom0_vcpus_pin dom0_mem=<at least 512M>

Avez-vous essayé de passer un périphérique PCI ethernet physique au domU ? Les performances devraient s'en trouver améliorées.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X