tcpdump augmente les performances udp

13

J'exécute un ensemble de tests de charge pour déterminer les performances de la configuration suivante:

Node.js test suite (client) --> StatsD (server) --> Graphite (server)

En bref, la suite de tests node.js envoie une quantité définie de métriques toutes les x secondes à une instance StatsD située sur un autre serveur. StatsD vide ensuite à son tour les métriques chaque seconde dans une instance Graphite située sur le même serveur. Je regarde ensuite combien de métriques ont été réellement envoyées par la suite de tests et combien ont été reçues par Graphite pour déterminer la perte de paquets entre la suite de tests et Graphite.

Cependant, j'ai remarqué que j'obtenais parfois des taux de chute de paquets très importants (notez qu'il est envoyé avec le protocole UDP), allant de 20 à 50%. C'est donc à ce moment-là que j'ai commencé à chercher où ces paquets étaient abandonnés, car cela pourrait être un problème de performances avec StatsD. J'ai donc commencé à enregistrer les métriques dans chaque partie du système pour localiser où cette baisse s'est produite. Et c'est là que les choses deviennent étranges.

J'utilise tcpdump pour créer un fichier de capture que j'inspecte une fois le test terminé. Mais chaque fois que j'exécute les tests avec tcpdump en cours d'exécution, la perte de paquets est presque inexistante! Il semble que tcpdump augmente en quelque sorte les performances de mes tests et je ne peux pas comprendre pourquoi et comment cela se fait. J'exécute la commande suivante pour enregistrer les messages tcpdump sur le serveur et le client:

tcpdump -i any -n port 8125 -w test.cap

Dans un cas de test particulier, j'envoie 40000 métriques / s. Le test lors de l'exécution de tcpdump a une perte de paquets d'environ 4% tandis que celui sans a une perte de paquets d'environ 20%

Les deux systèmes fonctionnent en tant que VM Xen avec la configuration suivante:

  • Intel Xeon E5-2630 v2 à 2,60 GHz
  • 2 Go de RAM
  • Ubuntu 14.04 x86_64

Choses que j'ai déjà vérifiées pour les causes potentielles:

  • Augmentation de la taille de réception / d'envoi du tampon UDP.
  • Charge CPU affectant le test. (charge maximale de 40 à 50%, côté client et côté serveur)
  • Exécuter tcpdump sur des interfaces spécifiques au lieu de 'any'.
  • Exécuter tcpdump avec '-p' pour désactiver le mode promiscuous.
  • Exécution de tcpdump uniquement sur le serveur. Cela a entraîné une perte de paquets de 20% et ne semble pas avoir d'impact sur les tests.
  • Exécution de tcpdump uniquement sur le client. Cela a entraîné une augmentation des performances.
  • Augmentation de netdev_max_backlog et netdev_budget à 2 ^ 32-1. Cela n'a fait aucune différence.
  • J'ai essayé tous les paramètres possibles du mode promiscuous sur chaque nic (serveur allumé et client éteint, serveur éteint et client allumé, les deux allumés, les deux éteints). Cela n'a fait aucune différence.
Ruben Homs
la source
3
Par défaut, tcpdump met votre interface réseau en mode promiscuous. Vous voudrez peut-être passer l' -poption pour ignorer cela pour voir si cela fait une différence.
Zoredache
Vous exécutez donc tcpdump à la fois sur le client et sur le serveur, et le taux de perte de paquets baisse? Que se passe-t-il si vous l'exécutez uniquement sur le client et que se passe-t-il si vous l'exécutez uniquement sur le serveur? (Et, oui, essayez également de désactiver le mode promiscuité, et essayez peut-être également de capturer sur l'interface réseau spécifique utilisée pour le test plutôt que sur le périphérique «tout», pour voir si cela fait une différence.)
Merci pour vos commentaires. J'ai essayé vos deux recommandations et modifié ma question pour refléter ce que j'ai essayé, mais cela n'a pas affecté le problème.
Ruben Homs,
Est-ce que mettre des nics sur les deux machines en mode promiscuous a le même effet que d'exécuter tcpdump? ifconfig eth0 promiscactive et ifconfig eth0 -promiscdésactive le mode promiscuous sur eth0. Si cela fait la différence, essayez de comparer les 4 combinaisons possibles de promisc on / off sur les deux machines. Cela pourrait aider à identifier la source des problèmes.
Fox
@ Fox Merci pour la réponse! J'ai essayé toutes les combinaisons possibles pour tous les nic, mais sans différence de résultats. J'ai mis à jour ma question pour refléter cela.
Ruben Homs

Réponses:

10

Lorsque tcpdump est en cours d'exécution, il sera assez rapide à lire dans les trames entrantes. Mon hypothèse est que les paramètres de tampon de l'anneau de paquets de la carte réseau peuvent être un peu sur la petite taille; lorsque tcpdump est en cours d'exécution, il se vide plus rapidement.

Si vous êtes abonné à Red Hat, cet article de support est très utile. Présentation de la réception des paquets . Il contient certaines choses que je ne pense pas que vous ayez encore envisagées.

Considérez comment votre système gère les IRQ; envisagez d'augmenter le «poids_dev» de l'interface réseau (ce qui signifie plus de paquets lus de la carte réseau vers l'espace utilisateur); regardez à quelle fréquence l'application lit le socket (peut-elle utiliser un thread dédié, y a-t-il des problèmes connus / solution de contournement concernant l'évolutivité).

Augmentez le tampon de trame NIC (en utilisant la ethtoolcommande - regardez les --set-ringarguments etc.).

Regardez 'recevoir côté mise à l'échelle' et utilisez au moins autant de threads de réception pour lire le trafic.

Je me demande si tcpdump fait quelque chose de cool comme l'utilisation du support du noyau pour les tampons en anneau de paquets . Cela aiderait à expliquer le comportement que vous voyez.

Cameron Kerr
la source
Comme il s'agit d'un environnement Xen, vous devriez probablement le faire (au moins une partie) sur l'hôte Xen.
Cameron Kerr
C'est quelque chose auquel je n'avais pas pensé avant, des trucs très intéressants, merci! J'essaierai ceci une fois que j'aurai accès à l'hôte Xen et je vous ferai savoir comment cela se passe.
Ruben Homs
2

Quel gouverneur de pouvoir utilisez-vous? J'ai vu des comportements similaires avec un gouverneur "à la demande" ou "conservateur".

Essayez d'utiliser le gouverneur "performance" et de désactiver toutes les fonctionnalités d'économie d'énergie dans le BIOS du serveur.

Cela change-t-il quelque chose?

shodanshok
la source
J'ai du mal à savoir quel gouverneur de puissance j'utilise. J'ai essayé de courir cpufreq-infomais j'ai reçu un message disant no or unknown cpufreq driver is active on this CPU. Aussi lors de son utilisation cpupower frequency-inforevient no or unknown cpufreq driver is active on this CPU. Bien que je ne puisse pas le confirmer pour le moment, le site Web du fabricant de la machine virtuelle me porte à croire qu'il fonctionne en mode "performance" car j'ai un processeur Intel.
Ruben Homs
Pouvez-vous afficher la sortie des commandes suivantes? 1) cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor2) cat /proc/cpuinfo3)lsmod | grep cpu
shodanshok
Et voilà
Ruben Homs
1

Une autre façon est le ip_conntarckmodule, êtes-vous sûr que votre linux-box peut accepter une nouvelle connexion? test via:

root@debian:/home/mohsen# sysctl net.ipv4.netfilter.ip_conntrack_max
net.ipv4.netfilter.ip_conntrack_max = 65536
root@debian:/home/mohsen# sysctl  net.ipv4.netfilter.ip_conntrack_count
net.ipv4.netfilter.ip_conntrack_count = 29

Vous devez tester

net.ipv4.netfilter.ip_conntrack_max >  net.ipv4.netfilter.ip_conntrack_count

si max == count, votre connexion maximale est complète et votre linux-box ne peut pas accepter de nouvelle connexion.
Si vous n'avez pas ip_conntrack, vous pouvez charger facilement viamodprobe ip_conntrack

Golfe Persique
la source
2
Et si c'est le cas, alors vous devriez regarder la cible NOTRACK dans le tableau «brut» pour empêcher le suivi de la connexion pour cela. Je l'ai fait récemment pour un serveur DNS occupé et il a supprimé iptables d'être le goulot d'étranglement et de provoquer des délais d'attente de résolution DNS.
Cameron Kerr
Et voici un exemple de la façon dont j'ai utilisé les règles NOTRACK pour qu'IPTables n'effectue aucun suivi de connexion pour le DNS UDP. distrused-it.blogspot.co.nz/2015/05/…
Cameron Kerr
1

Je soupçonne que le côté récepteur n'est tout simplement pas capable de gérer le taux de paquets et voici pourquoi:

  1. l'utilisation de tcpdump sur le client réduit les paquets perdus: tcpdump ralentit le client et donc le serveur voit un taux de packer beaucoup plus bas qu'il peut encore gérer partiellement. Vous devriez pouvoir confirmer cette hypothèse en vérifiant les compteurs de paquets RX / TX sur le client et le serveur

  2. vous avez mentionné que vous avez augmenté la taille de réception / d'envoi du tampon UDP, pourriez-vous détailler comment? Il est important que sur le serveur vous modifiiez à la fois rmem_max et rmem_default, par exemple: sysctl -w net.core.rmem_max=524287 sysctl -w net.core.wmem_max=524287 sysctl -w net.core.rmem_default=524287 sysctl -w net.core.wmem_default=524287

Tester vos paramètres

Arrêtez statsd et l'application de noeud, puis avec les systèmes inactifs, utilisez iperf pour tester le taux de paquets que le réseau / noyau peut gérer. Si vous pouvez diffuser 40K paquets / s avec iperf mais pas avec statsd, vous devez concentrer vos efforts sur le réglage de statsd.

Autres accordables

N'oubliez pas non plus de régler net.core.netdev_max_backlog : nombre maximal de paquets autorisés à mettre en file d'attente lorsqu'une interface particulière reçoit des paquets plus rapidement que le noyau ne peut les traiter.

unicoletti
la source