Réglage des paramètres de routage IP Linux - secret_interval et tcp_mem

30

Nous avons eu un petit problème de basculement avec l'une de nos machines virtuelles HAProxy aujourd'hui. Lorsque nous avons creusé, nous avons trouvé ceci:

26 janvier 07:41:45 noyau haproxy2: [226818.070059] __ratelimit: 10 rappels supprimés
26 janvier 07:41:45 noyau haproxy2: [226818.070064] Mémoire de socket insuffisante
26 janvier 07:41:47 noyau haproxy2: [226819.560048] Mémoire de socket insuffisante
26 janvier 07:41:49 noyau haproxy2: [226822.030044] Mémoire de socket insuffisante

Ce qui, selon ce lien , a apparemment à voir avec des paramètres par défaut bas pour net.ipv4.tcp_mem. Nous les avons donc augmentés de 4x par rapport à leurs valeurs par défaut (il s'agit d'Ubuntu Server, je ne sais pas si la saveur Linux est importante):

les valeurs actuelles sont: 45984 61312 91968
les nouvelles valeurs sont: 183936 245248 367872

Après cela, nous avons commencé à voir un message d'erreur bizarre:

26 janvier 08:18:49 noyau haproxy1: [2291.579726] Route de hachage trop longue!
26 janvier 08:18:49 noyau haproxy1: [2291.579732] Ajustez votre secret_interval!

Chut .. c'est un secret !!

Cela a apparemment à voir avec la valeur par /proc/sys/net/ipv4/route/secret_intervaldéfaut de 600 et contrôle le vidage périodique du cache de route

Le secret_intervalindique au noyau à quelle fréquence supprimer TOUTES les entrées de hachage de route, quelle que soit leur ancienneté. Dans notre environnement, c'est généralement mauvais. Le CPU sera occupé à reconstruire des milliers d'entrées par seconde chaque fois que le cache est effacé. Cependant, nous l'avons configuré pour s'exécuter une fois par jour pour éviter les fuites de mémoire (bien que nous n'en ayons jamais eu).

Bien que nous soyons heureux de réduire cela, il semble étrange de recommander de supprimer l'intégralité du cache de routage à intervalles réguliers , plutôt que de simplement retirer plus rapidement les anciennes valeurs du cache de routage.

Après quelques recherches, nous avons trouvé /proc/sys/net/ipv4/route/gc_elasticityce qui semble être une meilleure option pour contrôler la taille de la table de routage:

gc_elasticitypeut être décrit comme la profondeur moyenne du compartiment que le noyau acceptera avant de commencer à expirer les entrées de hachage de route. Cela aidera à maintenir la limite supérieure des itinéraires actifs.

Nous avons ajusté l'élasticité de 8 à 4, dans l'espoir que le cache de route se taille plus agressivement. Cela secret_intervalne nous semble pas correct. Mais il y a un tas de paramètres et on ne sait pas vraiment quelle est la bonne façon d'aller ici.

  • / proc / sys / net / ipv4 / route / gc_elasticity (8)
  • / proc / sys / net / ipv4 / route / gc_interval (60)
  • / proc / sys / net / ipv4 / route / gc_min_interval (0)
  • / proc / sys / net / ipv4 / route / gc_timeout (300)
  • / proc / sys / net / ipv4 / route / secret_interval (600)
  • / proc / sys / net / ipv4 / route / gc_thresh (?)
  • rhash_entries (paramètre du noyau, valeur par défaut inconnue?)

Nous ne voulons pas faire le routage Linux pire , donc nous sommes un peu peur de jouer avec certains de ces paramètres.

Quelqu'un peut-il indiquer les paramètres de routage les mieux adaptés, pour une instance HAProxy à fort trafic?

Jeff Atwood
la source

Réponses:

28

Je n'ai jamais rencontré ce problème. Cependant, vous devriez probablement augmenter la largeur de votre table de hachage afin de réduire sa profondeur. En utilisant "dmesg", vous verrez combien d'entrées vous avez actuellement:

$ dmesg | grep '^IP route'
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)

Vous pouvez modifier cette valeur avec le paramètre de ligne de commande de démarrage du noyau rhash_entries. Essayez-le d'abord à la main, puis ajoutez-le à votre lilo.confou grub.conf.

Par exemple: kernel vmlinux rhash_entries=131072

Il est possible que votre table de hachage soit très limitée car vous avez affecté peu de mémoire à votre machine virtuelle HAProxy (la taille du hachage de l'itinéraire est ajustée en fonction de la RAM totale).

Concernant tcp_mem, soyez prudent. Vos paramètres initiaux me font penser que vous utilisiez 1 Go de RAM, dont 1/3 pourrait être alloué aux sockets TCP. Vous avez maintenant alloué 367872 * 4096 octets = 1,5 Go de RAM aux sockets TCP. Vous devez faire très attention à ne pas manquer de mémoire. Une règle d'or consiste à allouer 1/3 de la mémoire à HAProxy et 1/3 à la pile TCP et le dernier 1/3 au reste du système.

Je soupçonne que votre message "out of socket memory" provient des paramètres par défaut dans tcp_rmemet tcp_wmem. Par défaut, vous avez 64 Ko alloués en sortie pour chaque socket et 87 Ko en entrée. Cela signifie un total de 300 Ko pour une connexion proxy, juste pour les tampons de socket. Ajoutez à cela 16 ou 32 Ko pour HAProxy, et vous voyez qu'avec 1 Go de RAM, vous ne supporterez que 3000 connexions.

En modifiant les paramètres par défaut de tcp_rmemet tcp_wmem( paramètre du milieu), vous pouvez réduire considérablement la mémoire. J'obtiens de bons résultats avec des valeurs aussi basses que 4096 pour le tampon d'écriture et 7300 ou 16060 pouces tcp_rmem(5 ou 11 segments TCP). Vous pouvez modifier ces paramètres sans redémarrer, mais ils ne s'appliqueront qu'aux nouvelles connexions.

Si vous préférez ne pas trop toucher à vos systèmes , le dernier HAProxy, 1.4-dev8, vous permet de modifier ces paramètres à partir de la configuration globale et par côté (client ou serveur).

J'espère que cela aide!

Willy Tarreau
la source
8

Le Out of socket memory errorest souvent trompeur. La plupart du temps, sur des serveurs face à Internet, il ne pas indiquer tout problème lié à l' exécution de mémoire. Comme je l'ai expliqué plus en détail dans un article de blog , la raison la plus courante est le nombre de sockets orphelins. Un socket orphelin est un socket qui n'est pas associé à un descripteur de fichier. Dans certaines circonstances, le noyau émettra le Out of socket memory errormême si vous êtes 2x ou 4x loin de la limite ( /proc/sys/net/ipv4/tcp_max_orphans). Cela se produit fréquemment dans les services accessibles sur Internet et est parfaitement normal. Dans ce cas, la bonne ligne de conduite consiste à régler tcp_max_orphansau moins 4x le nombre d'orphelins que vous voyez normalement avec votre trafic de pointe.

N'écoutez aucun conseil qui recommande le réglage tcp_memou tcp_rmemou à tcp_wmemmoins que vous ne sachiez vraiment ce que vous faites. Ceux qui donnent ces conseils ne le font généralement pas. Leur vaudou est souvent faux ou inapproprié pour votre environnement et ne résoudra pas votre problème. Cela pourrait même aggraver les choses.

tsuna
la source
1
Lorsque cela se produit, le message est différent dans dmesg, vous voyez "trop ​​de sockets orphelins". Cependant, je suis d'accord avec vous que les orphelins peuvent consommer une énorme quantité de mémoire.
Willy Tarreau
Lorsque vous dépassez le nombre de /proc/sys/net/ipv4/tcp_max_orphansvous rencontrerez une erreur différente. La pile entière de Stack Exchange, par exemple, a /proc/sys/net/ipv4/tcp_max_orphans65536 et se /proc/net/sockstattraduit par TCP: inuse 2996 orphan 171 tw 15972 alloc 2998 mem 1621 - une différence qui ne peut pas être ignorée.
Geoff Dalgas
-4

Nous ajustons régulièrement certains de ces paramètres. Notre standard pour les plateformes de trading à haut débit et à faible latence est:

net.ipv4.tcp_rmem = 4096 16777216 33554432
net.ipv4.tcp_wmem = 4096 16777216 33554432
net.ipv4.tcp_mem = 4096 16777216 33554432
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 30000
net.core.netdev_max_backlog = 30000
Scott Alan Miller
la source
1
selon les calculs de Willy, cela signifie que votre pression de mémoire standard # (chiffre du milieu) est de 68 Go?! Trois fois (rmem, wmem, mem) ??
Jeff Atwood, du
10
Ces paramètres ajustables sont erronés et sont très fréquemment trouvés dans des environnements de banc, puis copiés-collés à l'aveugle. Ils n'auront aucun problème avec seulement quelques sessions simultanées, mais même avec 100 sockets TCP, vous allouerez 3,2 Go de RAM. Tant que la latence est faible, vous ne remarquerez rien de suspect. Il vous suffit de débrancher une machine distante pendant un transfert pour voir le remplissage des tampons de sortie, ou de geler une tâche locale et de voir le remplissage du tampon d'entrée. C'est fou ...
Willy Tarreau
6
Jeff, ce n'est pas trois fois. tcp_mem est dans les pages et définit la taille globale. tcp_rmem et tcp_wmem sont en octets et définissent la taille par socket.
Willy Tarreau
Ces paramètres ajustables semblent incorrects, pour les serveurs simultanés avec de petites données que vous ne voulez pas réserver autant de tampons de socket et tcp_mem est totalement différent de r / wmem, l'utilisation des mêmes nombres n'a pas vraiment de sens (l'un est octets par connexion l'autre) pages par système)
Eckes