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.
-p
option pour ignorer cela pour voir si cela fait une différence.ifconfig eth0 promisc
active etifconfig eth0 -promisc
dé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.Réponses:
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
ethtool
commande - regardez les--set-ring
arguments 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.
la source
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?
la source
cpufreq-info
mais j'ai reçu un message disantno or unknown cpufreq driver is active on this CPU
. Aussi lors de son utilisationcpupower frequency-info
revientno 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.cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
2)cat /proc/cpuinfo
3)lsmod | grep cpu
Une autre façon est le
ip_conntarck
module, êtes-vous sûr que votre linux-box peut accepter une nouvelle connexion? test via:Vous devez tester
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 via
modprobe ip_conntrack
la source
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:
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
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.
la source