Pourquoi TCP accepte-t-il si mal les performances sous Xen?

89

La vitesse à laquelle mon serveur peut accepter () les nouvelles connexions TCP entrantes est vraiment mauvaise sous Xen. Le même test sur du matériel en métal nu montre des accélérations de 3-5x.

  1. Comment se fait-il que ce soit si grave 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 étudié les goulets d'étranglement des performances d'un serveur Java développé en interne sous Xen. Le serveur parle HTTP et répond aux appels de connexion / demande / réponse / déconnexion TCP simples.

Mais même en envoyant des charges de trafic au serveur, il ne peut accepter plus de 7 000 connexions TCP par seconde (sur une instance EC2 à 8 cœurs, c1.xlarge exécutant Xen). Au cours du test, le serveur présente également un comportement étrange dans lequel un cœur (pas nécessairement le processeur 0) est très chargé> 80%, tandis que les autres coeurs restent presque inactifs. Cela me porte à penser que le problème est lié à la virtualisation noyau / sous-jacente.

Lorsque je teste le même scénario sur une plate-forme simple, non virtualisée, les résultats du test indiquent des taux d'acceptation TCP () supérieurs à 35 000 / seconde. Ceci sur une machine Core i5 4 utilisant Ubuntu avec tous les cœurs presque complètement saturés. Pour moi, ce genre de chiffre semble à peu près correct.

Sur l'instance Xen encore, j'ai essayé d'activer / modifier presque tous les paramètres présents dans sysctl.conf. Y compris l’activation de Recevoir le flux de réception et le flux de réception, le pilotage et l’association de threads / processus aux CPU, mais sans gains apparents.

Je sais que des performances dégradées sont à prévoir lors de l'exécution de la virtualisation. Mais à ce degré? Un serveur nu plus lent et plus performant que 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 cette question et en identifiant le problème, j'ai découvert que l' outil de test de performances de netperf pouvait simuler le même scénario que celui que je rencontre. En utilisant le test TCP_CRR de netperf, j'ai collecté divers rapports de différents serveurs (virtualisés et non virtuels). Si vous souhaitez contribuer à quelques résultats ou consulter mes rapports actuels, veuillez consulter https://gist.github.com/985475.

Comment savoir si ce problème n'est pas dû à un logiciel mal écrit?

  1. Le serveur a été testé sur du matériel nu et il sature presque tous les cœurs disponibles.
  2. Lorsque vous utilisez des connexions TCP persistantes, le problème disparaît.

Pourquoi est-ce important?

Chez ESN (mon employeur), je suis le chef de projet de Beaconpush , un serveur Comet / Web Socket écrit en Java. Même s'il est très performant et qu'il peut saturer presque toute la bande passante qui lui est attribuée dans des conditions optimales, il reste 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 configurées / supprimées. Nous essayons d’atténuer ce risque en maintenant les connexions en vie le plus longtemps possible. Mais au final, la performance accept () est ce qui empêche nos cœurs de tourner et nous n’aimons pas cela.


Mise à jour 1

Quelqu'un a posté cette question sur Hacker News , il y a aussi quelques questions / réponses. Mais je vais essayer de garder cette question à jour avec les informations que je trouve au fur et à mesure.

Matériel / plates-formes sur lesquelles j'ai testé ceci:

  • EC2 avec les types d'instance c1.xlarge (8 cœurs, 7 Go de RAM) et cc1.4xlarge (2 x Intel Xeon X5570, 23 Go de RAM). Les AMI utilisés étaient ami-08f40561 et ami-1cad5275 respectivement. Quelqu'un a également souligné que les "groupes de sécurité" (c'est-à-dire le pare-feu de l'EC2) pourraient également affecter. Mais pour ce scénario de test, je n'ai essayé que sur localhost d'éliminer des 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 virtualisés privés exécutant Xen. L'un d'eux n'avait aucune charge avant le test, mais ne faisait aucune différence.
  • Serveur Xen privé dédié chez Rackspace. À peu près les mêmes résultats là-bas.

Je suis en train de réexécuter ces tests et de remplir les rapports à l' adresse https://gist.github.com/985475. Si vous souhaitez aider, donnez vos chiffres. C'est facile!

(Le plan d'action a été déplacé vers une réponse consolidée séparée)

cgbystrom
la source
3
C'est un excellent travail qui consiste à identifier un problème, mais je pense que vous seriez beaucoup mieux servi sur une liste de diffusion spécifique à Xen, un forum de support ou même le site de rapport de bogue xensource . Je crois que cela pourrait être un bug du planificateur - si vous prenez vos nombres de 7 000 connexions * 4 cœurs / 0,80 charge de processeur, vous obtenez exactement 35 000 - le nombre que vous obtiendrez lorsque 4 cœurs seraient complètement saturés.
le-wabbit
Ah, et encore une chose: essayez une version du noyau différente (peut-être plus récente) pour votre invité, si vous le pouvez.
le-wabbit
@ syneticon-dj Merci. Je l'ai essayé sur un cc1.4xlarge à 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 costaud de ce type d'instance.
cgbystrom
6
merci de garder cela à jour avec les réponses du pays hôte, c'est une excellente question. Je suggère de transformer le plan d'action en une réponse consolidée, peut-être - car ce sont toutes des réponses possibles au problème.
Jeff Atwood
@jeff Déplacez le plan d'action, cochez.
cgbystrom

Réponses:

27

En ce moment: la performance des petits paquets est nulle 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 KVM?), Cela est dû aux performances des paquets de taille réduite dans Xen et également à KVM. C'est un problème connu avec la virtualisation et selon lui, l'ESX de VMWare s'en occupe beaucoup mieux. Il a également noté que KVM apporte de nouvelles fonctionnalités conçues pour 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 arrive avec une réponse définitive :)

Iain Kay de la liste de diffusion xen-users a compilé ce graphique: graphique netperf Notez 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 de HN :

  1. Soumettez ce problème à une liste de diffusion spécifique à Xen et au bugzilla de xensource, comme suggéré par syneticon-dj Un message a été posté sur la liste des utilisateurs de xen , en attente de 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 pouvoir voir un cas d'utilisation plus réel que netperf.

  3. Essayez une instance d'invité PV Xen 32 bits, car 64 bits pourraient entraîner davantage de temps système dans Xen. Quelqu'un a mentionné cela sur HN. 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 pourrait apparemment améliorer les performances car la poignée de main se produirait dans le noyau. Je n'ai pas eu de chance avec ça.

  5. Augmentez l'arriéré de 1024 à quelque chose de beaucoup plus élevé, également suggéré par abofh sur HN. Cela pourrait aussi aider puisque guest 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. Recherchez les débordements de la file d'attente d'écoute et de syncache dans netstat -s (suggéré par mike_esspe sur HN).

  8. Divisez la gestion des interruptions entre plusieurs cœurs (RPS / RFS que j'ai essayé d'activer plus tôt sont supposés le faire, mais cela pourrait valoir la peine d'essayer à nouveau). Proposé par adamt at HN.

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

cgbystrom
la source
2
+1 Diffusez les résultats lorsque vous avez découvert!
Chrisaycock
Quelqu'un m'a piqué sur Twitter concernant cette question. Malheureusement, il semble que ces problèmes persistent. Je n'ai pas fait beaucoup de recherches depuis l'année dernière. Xen PEUT avoir amélioré pendant ce temps, je ne sais pas. Le développeur de KVM a également indiqué qu’il abordait des problèmes de ce type. Cela pourrait valoir la peine d'être poursuivi. En outre, une autre recommandation que j'ai entendue est d'essayer OpenVZ au lieu de Xen / KVM car cela ajoute moins ou pas de superposition / interception d'appels système.
cgbystrom
21

De manière anecdotique, j'ai constaté que le fait de désactiver l'accélération matérielle des cartes réseau améliore considérablement les performances du réseau sur le contrôleur Xen (également vrai pour LXC):

Scatter-recueillir Accell:

/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 votre périphérique réseau sur l'hôte de l'hyperviseur. Vous devrez le configurer pour l'éteindre à chaque démarrage. YMMV.

Matt Bailey
la source
Je seconde ceci. J'avais un serveur Windows 2003 sous Xen qui souffrait d'horribles problèmes de perte de paquets dans des conditions de débit élevé. Le problème a disparu lorsque j'ai désactivé le déchargement du segment TCP
Rupello,
Merci. J'ai mis à jour le "plan d'action" de la question initiale avec vos suggestions.
cgbystrom
3

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

Accepter n'est qu'un autre appel système, et les nouvelles connexions ne diffèrent que par le fait que les premiers paquets auront des indicateurs spécifiques - un hyperviseur tel que Xen ne devrait absolument pas voir de différence. D'autres éléments de votre configuration peuvent notamment: dans EC2 par exemple, je ne serais pas surpris que des groupes de sécurité aient quelque chose à voir avec cela; conntrack réduirait également de moitié le nombre de nouvelles connexions acceptées (PDF) .

Enfin, il semble exister des combinaisons processeur / noyau qui entraînent une utilisation / un blocage étrange du processeur sur EC2 (et probablement Xen en général), sur lequel Blrato a récemment écrit un article .

deubeulyou
la source
J'ai mis à jour la question et clarifié le matériel sur lequel j'ai déjà essayé. abofh a également suggéré d'augmenter l'arriéré au-delà de 1024 afin d'accélérer le nombre de accept () possibles lors d'une tranche d'exécution pour l'invité. En ce qui concerne conntrack, je dois absolument vérifier que de telles choses sont désactivées, merci. J'ai lu cet article de Liberato, mais vu la quantité de matériel différent sur lequel j'ai essayé, cela ne devrait pas être le cas.
cgbystrom
0

Assurez-vous que vous avez désactivé iptables et autres hooks dans le code de pontage dans dom0. Évidemment, cela ne s'applique qu'au pontage de la configuration Xen en réseau.

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 des plus petits (processeur à 4 cœurs) dédient un cpu core à Xen dom0 et l'épinglent. Options de démarrage de l'hyperviseur:

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

Avez-vous essayé de transmettre un périphérique Ethernet physique Ethernet à domU? Il devrait y avoir une belle augmentation des performances.

Kupson
la source