10/20 / 40Gbps nginx gros fichiers cache serveur web [20Gbps atteint]


10

Je voudrais découvrir la meilleure configuration / matériel possible pour fournir 40 Gbit / s à partir d'un seul serveur dans cette question.

Situation

Nous avons un serveur proxy de partage vidéo qui décharge les pics des serveurs de stockage lents derrière lui. Tout le trafic est uniquement HTTP. Le serveur agit comme un proxy inverse (fichiers qui ne sont pas mis en cache sur le serveur) et un serveur Web (fichiers qui sont stockés sur des lecteurs locaux).

Il y a actuellement quelque chose comme 100 To de fichiers et en croissance sur les serveurs de stockage backend.

Le mécanisme de mise en cache est implémenté indépendamment et cette question ne concerne pas la mise en cache elle-même car elle fonctionne très bien - fournit actuellement 14 Gbit / s, ne passe aux serveurs principaux que 2 Gbit / s. L'utilisation du cache est donc bonne.

Objectif

Obtenez un débit de 40 Gbit / s ou plus à partir d'une seule machine.

Matériel 1

HW: Supermicro SC825, X11SSL-F, Xeon E3-1230v5 (4C/8T@3.4GHz), 16 Go de RAM DDR4, 2x Supermicro 10G STGN-i1S (LACP L3 + 4)

SSD: 1x 512 Go Samsung, 2x 500 Go Samsung, 2x480 Go Intel 535, 1x 240 Go Intel S3500

Système:

  • irqbalancer arrêté
  • set_irq_affinity pour chaque interface (via script dans l'archive du pilote ixgbe)
  • ixgbe-4.3.15
  • Date limite du planificateur d'E / S
  • iptables vides (modules déchargés)
  • Système de fichiers: XFS

Nginx:

  • envoyer le fichier
  • fils aio
  • directio 1M
  • tcp_nopush sur
  • tcp_nodelay sur

entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici

Comme on le voit sur les graphiques, nous avons pu pousser 12,5 Gbps. Malheureusement, le serveur ne répondait pas.

Il y a 2 choses qui ont attiré mon attention. Le premier est une quantité élevée d'IRQ. Dans ce cas, je n'ai malheureusement pas de graphiques de / proc / interrupts. La deuxième chose était une charge système élevée, ce qui, je pense, était dû au fait que kswapd0 avait des problèmes pour fonctionner avec 16 Go de RAM uniquement.

Matériel 2

HW: Supermicro SC119TQ, X10DRW-i, 2x Xeon E5-2609v4 (8C/8T@1.70GHz), 128 Go de RAM DDR4, 2x Supermicro 10G STGN-i1S

SSD, la configuration du système est la même que pour le matériel 1. Nginx est sendfile (aio / sendfile comparé plus loin).

entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici

Cela semble mieux, alors maintenant que nous avons un serveur, qui fonctionne dans les pics, nous pouvons essayer quelques optimisations.

Sendfile vs aio threads

J'ai essayé de désactiver sendfile et d'utiliser des threads aio à la place.

  • envoyer le fichier
  • fils aio
  • directio 1M (qui correspond à tous les fichiers que nous avons)

contre

  • sendfile sur

Puis à 15h00, je suis revenu à sendfile et j'ai rechargé nginx (il a donc fallu un certain temps pour terminer les connexions existantes). Il est bon que l'utilisation du lecteur (mesurée par iostat) ait diminué. Rien n'a changé sur le trafic (malheureusement zabbix a décidé de ne pas collecter les données de bond0).

entrez la description de l'image ici entrez la description de l'image ici entrez la description de l'image ici

sendfile on / off

Je viens d'essayer d'activer / désactiver l'envoi. Rien n'a changé, sauf la reprogrammation des interruptions.

entrez la description de l'image ici entrez la description de l'image ici

irqbalancer en tant que serveur / cron / désactivé

Comme @lsd l'a mentionné, j'ai essayé de configurer irqbalancer pour qu'il soit exécuté via cron:

*/5 * * * *   root    /usr/sbin/irqbalance --oneshot --debug 3 > /dev/null

Malheureusement, cela n'a pas aidé dans mon cas. L'une des cartes réseau a commencé à se comporter de manière étrange:

entrez la description de l'image ici

Je n'ai pas pu trouver ce qui n'allait pas dans les graphiques et comme c'est arrivé le lendemain, je me suis connecté au serveur et j'ai vu qu'un cœur était à 100% (utilisation du système).

J'ai essayé de démarrer irqbalance en tant que service, le résultat était toujours le même.

Ensuite, j'ai décidé d'utiliser le script set_irq_affinity et il a résolu le problème immédiatement et le serveur a poussé à nouveau 17Gbps.

Matériel 3

Nous avons fait la mise à niveau vers un nouveau matériel: châssis de lecteurs 2U 24 (+2) (6xSFF), 2x Xeon E5-2620v4, 64 Go de RAM DDR4 (modules 4x16 Go), 13x SSD, 2x cartes réseau Supermicro (avec puce Intel). Les nouveaux processeurs ont beaucoup amélioré les performances.

La configuration actuelle reste - sendfile, etc. La seule différence est que nous ne laissons qu'un seul processeur gérer les deux cartes réseau (via le script set_irq_affinity).

La limite de 20 Gbps a été atteinte.

entrez la description de l'image ici entrez la description de l'image ici

Prochain but? 30 Gbps.


N'hésitez pas à me tirer des idées pour améliorer les performances. Je serai heureux de le tester en direct et de partager quelques graphiques lourds ici.

Avez-vous des idées sur la façon de gérer une grande quantité de SoftIRQ sur le processeur?

Ce n'est pas une question de planification de capacité - j'ai déjà le matériel et le trafic. Je peux toujours répartir le trafic sur plusieurs serveurs (ce que je devrai faire à l'avenir de toute façon) et résoudre le problème avec de l'argent. Il s'agit cependant d'une question sur l'optimisation du système et l'optimisation des performances dans un scénario réel réel.



4
Vous dites que cela ne concerne pas la planification de la capacité, mais il me semble qu'essayer de pousser 40 Gbit / s sur un seul serveur est révélateur de problèmes de capacité.
ceejayoz

5
Juste un côté intéressant, à un ancien emploi, ils ont désactivé le service d'irqbalance, mais ont toujours exécuté un travail cron qui a exécuté irqbalance toutes les 15 minutes environ. Nous avons donc toujours profité de l'irqbalance, mais pas à la fréquence du service.
lsd

Mise à jour: Ajout du test d'activation / désactivation de sendfile. @lsd: J'essaierai d'utiliser irqbalance de manière autonome via cron la semaine prochaine. Voyons quel sera l'impact.
Yarik Dot

1
Qu'avez-vous utilisé pour créer les graphiques?
Johnny V

Réponses:


9

Avertissement : Le même conseil s'applique à tous les services poussant plus de 10 Gbps. Inclus mais non limité aux équilibreurs de charge, aux serveurs de mise en cache, aux serveurs Web (HAProxy, Varnish, nginx, tomcat, ...)

Ce que tu veux faire est mal, ne le fais pas

Utilisez plutôt un CDN

Les CDN sont destinés à fournir du contenu statique cachable. Utilisez le bon outil pour le travail (akamai, MaxCDN, cloudflare, cloudfront, ...)

Tout CDN, même gratuit, fera mieux que tout ce que vous pouvez réaliser par vous-même.

Mettre à l'échelle horizontalement à la place

Je m'attends à ce qu'un seul serveur gère 1 à 5 Gbits / s sans la peaufiner (remarque: servir uniquement des fichiers statiques). Le 8-10Gbps est généralement à portée de main avec un réglage avancé.

Néanmoins, il existe de nombreuses limites strictes à ce qu'une seule boîte peut prendre. Vous devriez préférer mettre à l'échelle horizontalement.

Exécutez une seule boîte, essayez des choses, mesurez, comparez, optimisez ... jusqu'à ce que cette boîte soit fiable et fiable et que ses capacités soient bien déterminées, puis placez plus de boîtes comme celle-ci avec un équilibreur de charge global devant.

Il existe quelques options globales d'équilibrage de charge: la plupart des CDN peuvent le faire, DNS roundrobin, équilibreurs de charge ELB / Google ...

Ignorons les bonnes pratiques et faisons-le quand même

Comprendre le modèle de trafic

            WITHOUT REVERSE PROXY

[request ]  user ===(rx)==> backend application
[response]  user <==(tx)===     [processing...]

Il y a deux choses à considérer: la bande passante et la direction (émission ou réception).

Les petits fichiers sont 50/50 tx / rx car les en-têtes HTTP et la surcharge TCP sont plus gros que le contenu du fichier.

Les gros fichiers sont 90/10 tx / rx car la taille de la demande est négligeable par rapport à la taille de la réponse.

            WITH REVERSE PROXY

[request ]  user ===(rx)==> nginx ===(tx)==> backend application
[response]  user <==(tx)=== nginx <==(rx)===     [processing...]

Le proxy inverse relaie tous les messages dans les deux sens. La charge est toujours de 50/50 et le trafic total est doublé.

Cela devient plus complexe avec la mise en cache activée. Les demandes peuvent être détournées vers le disque dur, dont les données peuvent être mises en cache en mémoire.

Remarque : je vais ignorer l'aspect de la mise en cache dans ce post. Nous nous concentrerons sur l'obtention de 10 à 40 Gbit / s sur le réseau. Savoir si les données proviennent du cache et optimiser ce cache est un autre sujet, il est poussé dans les deux sens.

Limitations Monocore

L'équilibrage de charge est monocore (en particulier l'équilibrage TCP). L'ajout de cœurs ne le rend pas plus rapide, mais il peut le ralentir.

Idem pour l'équilibrage HTTP avec des modes simples (par exemple IP, URL, basé sur les cookies. Le proxy inverse lit les en-têtes à la volée, il n'analyse pas et ne traite pas les requêtes HTTP au sens strict).

En mode HTTPS, le décryptage / cryptage SSL est plus intensif que tout le reste requis pour le proxy. Le trafic SSL peut et doit être réparti sur plusieurs cœurs.

SSL

Étant donné que vous faites tout sur SSL. Vous voudrez optimiser cette partie.

Crypter et décrypter 40 Gbps à la volée est tout un exploit.

Prenez un processeur de dernière génération avec les instructions AES-NI (utilisées pour les opérations SSL).

Ajustez l'algorithme utilisé par les certificats. Il existe de nombreux algorithmes. Vous voulez celui qui est le plus efficace sur votre CPU (faites des analyses comparatives) TOUT en étant pris en charge par les clients ET en étant juste assez sécurisé (pas de sur-cryptage nécessaire).

IRQ et épinglage de noyau

La carte réseau génère des interruptions (IRQ) lorsqu'il y a de nouvelles données à lire et que le CPU est préempté pour gérer immédiatement la file d'attente. Il s'agit d'une opération exécutée dans le noyau et / ou les pilotes de périphérique et elle est strictement monocore.

Il peut être le plus grand consommateur de CPU avec des milliards de paquets sortant dans toutes les directions.

Attribuez à la carte réseau un numéro IRQ unique et épinglez-le à un cœur spécifique (voir les paramètres Linux ou BIOS).

Épinglez le proxy inverse à d'autres cœurs. Nous ne voulons pas que ces deux choses interfèrent.

Adaptateur Ethernet

La carte réseau fait le gros du travail. Tous les appareils et fabricants ne sont pas égaux en matière de performances.

Oubliez l'adaptateur intégré sur les cartes mères (peu importe si la carte mère du serveur ou du consommateur), elles sont nulles.

Déchargement TCP

TCP est un protocole très intensif en termes de traitement (sommes de contrôle, ACK, retransmission, réassemblage de paquets, ...) Le noyau gère l'essentiel du travail mais certaines opérations peuvent être déchargées sur la carte réseau si elle le supporte.

Nous ne voulons pas seulement une carte relativement rapide , nous en voulons une avec toutes les cloches et les sifflets.

Oubliez Intel, Mellanox, Dell, HP, peu importe. Ils ne supportent pas tout cela.

Il n'y a qu'une seule option sur la table: SolarFlare - L'arme secrète des entreprises HFT et CDN.

Le monde est divisé en deux types de personnes: " Ceux qui connaissent SolarFlare " et " ceux qui ne le savent pas ". (le premier ensemble étant strictement équivalent à "des gens qui font du réseautage à 10 Gbit / s et qui se soucient de chaque bit "). Mais je m'égare, concentrons-nous: D

Réglage TCP du noyau

Il existe des options sysctl.confpour les tampons réseau du noyau. Ce que ces paramètres font ou ne font pas. Je ne sais vraiment pas.

net.core.wmem_max
net.core.rmem_max
net.core.wmem_default
net.core.rmem_default

net.ipv4.tcp_mem
net.ipv4.tcp_wmem
net.ipv4.tcp_rmem

Jouer avec ces paramètres est le signe définitif d'une suroptimisation (c'est-à-dire généralement inutile ou contre-productif).

Exceptionnellement, cela pourrait avoir un sens étant donné les exigences extrêmes.

(Remarque: 40 Gbit / s sur une seule boîte est une sur-optimisation. L'itinéraire raisonnable est de mettre à l'échelle horizontalement.)

Quelques limites physiques

Bande passante mémoire

Quelques chiffres sur la bande passante mémoire (principalement en Go / s): http://www.tweaktown.com/articles/6619/crucial-ddr4-memory-performance-overview-early-look-vs-ddr2-ddr3/index.html

Disons que la plage est de 150-300 Gbps pour la bande passante mémoire (limite maximale dans des conditions idéales).

Tous les paquets doivent être en mémoire à un moment donné. L'ingestion de données à un débit de 40 Gbit / s représente une lourde charge pour le système.

Restera-t-il le pouvoir de traiter les données? Eh bien, n'attendons pas trop nos attentes à ce sujet. Je dis juste ^^

Bus PCI-Express

PCIe 2.0 est de 4 Gbit / s par voie. PCIe 3.0 est de 8 Gbit / s par voie (tout n'est pas disponible pour la carte PCI).

Une carte réseau à 40 Gbit / s avec un seul port Ethernet est plus prometteuse que le bus PCIe si le connecteur a une longueur inférieure à 16x selon les spécifications v3.0.

Autre

Nous pourrions dépasser d'autres limites. Le fait est que le matériel a des limitations strictes inhérentes à la loi de la physique.

Un logiciel ne peut pas faire mieux que le matériel sur lequel il fonctionne.

L'épine dorsale du réseau

Tous ces paquets doivent finalement aller quelque part, traversant des commutateurs et des routeurs. Les commutateurs et le routeur 10 Gbps sont [presque] une marchandise. Les 40 Gbps ne le sont certainement pas.

De plus, la bande passante doit être de bout en bout, alors quel type de liens avez-vous jusqu'à l'utilisateur?

La dernière fois que j'ai vérifié avec mon gars du centre de données pour un petit projet côté utilisateur de 10 millions, il était assez clair qu'il n'y aurait que 2 x 10 Gbits de liens vers Internet au plus.

Disques durs

iostat -xtc 3

Les mesures sont divisées par lecture et écriture. Vérifiez la file d'attente (<1, c'est bien), la latence (<1 ms, c'est bien) et la vitesse de transfert (plus c'est élevé, mieux c'est).

Si le disque est lent, la solution est de mettre plus ET plus de SSD dans le raid 10. (notez que la bande passante SSD augmente linéairement avec la taille SSD).

Choix du CPU

L'IRQ et les autres goulots d'étranglement ne fonctionnent que sur un seul cœur, alors visez le processeur avec les performances monocœur les plus élevées (c'est-à-dire la fréquence la plus élevée).

Le chiffrement / déchiffrement SSL nécessite les instructions AES-NI, alors visez uniquement la dernière révision du processeur.

SSL bénéficie de plusieurs cœurs, alors visez de nombreux cœurs.

Pour faire court: le processeur idéal est le plus récent avec la fréquence la plus élevée disponible et de nombreux cœurs. Choisissez simplement le plus cher et c'est probablement tout: D

envoyer le fichier()

Sendfile ON

Tout simplement le plus grand progrès des noyaux modernes pour les serveurs Web hautes performances.

Note finale

1 SolarFlare NIC 40 Gbps (pin IRQ and core)
2 SolarFlare NIC 40 Gbps (pin IRQ and core)
3 nginx master process
4 nginx worker
5 nginx worker
6 nginx worker
7 nginx worker
8 nginx worker
...

Une chose épinglée sur un processeur. Voilà la voie à suivre.

Une carte réseau menant au monde extérieur. Une carte réseau menant au réseau interne. Le partage des responsabilités est toujours agréable (bien que la double carte réseau à 40 Gbit / s soit excessive).

C'est beaucoup de choses à peaufiner, dont certaines pourraient faire l'objet d'un petit livre. Amusez-vous à comparer tout cela. Revenez pour publier les résultats.


Les cartes réseau Solarflare ont été commandées il y a quelques semaines pour des tests. J'attends maintenant les conseils du support de Solarflare sur la façon de régler le système pour obtenir le maximum. performances possibles. Après ce test, je partagerai la configuration et les résultats.
Yarik Dot

1
Standing Ovation ....
James Pulley

Juste une mise à jour rapide sur les disques durs - l'utilisation de tout type de raid dans ce scénario (disques SSD) ne fonctionne pas correctement. Comme les SSD sont portés différemment, ils ont des performances différentes et avec un SSD lent dans le raid, les performances du raid peuvent être médiocres. Le meilleur scénario, qui fonctionne le mieux pour nous, est d'utiliser des disques uniques, sans aucun raid HW / SW.
Yarik Dot

0

Je ne peux pas encore commenter en raison de la réputation, alors je dois ajouter une réponse à la place ...

Dans le premier exemple, vous avez dit:

Il y a 2 choses qui ont attiré mon attention. Le premier est une quantité élevée d'IRQ. Dans ce cas, je n'ai malheureusement pas de graphiques de / proc / interrupts. La deuxième chose était une charge système élevée, ce qui, je pense, était dû au fait que kswapd0 avait des problèmes pour fonctionner avec 16 Go de RAM uniquement.

Je suis absolument d'accord que ce sont des points importants.

  1. Essayez d'utiliser l'agent collectd, qui peut collecter les IRQ et les stocker à l'aide de RRD.

  2. Avez-vous un tableau d'utilisation de la mémoire?

    En surface, cela ressemble à un problème de processeur, le% softirq élevé pourrait simplement pointer du doigt la mémoire, s'il y a beaucoup de défauts de page durs ou mous. Je pense que le cadeau est l'escalade soudaine des IRQ, au détriment du CPU du système vers 19h00.

D'après ce que je peux voir dans les spécifications, tout est identique sauf:

  • la mémoire
  • les modèles cpu - à moins que je ne me trompe, les repères indiqueraient qu'ils devraient être similaires, et dans ce genre de cas, je préférerais la boîte avec moins de cœurs plus rapides.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.