Marc Brooker, ingénieur chez Amazon Web Services (AWS), a levé le voile sur les malentendus concernant l'optimisation de la transmission de petits messages lors de l'utilisation de l'algorithme de Nagle, appliqué par défaut dans la pile TCP/IP. Les recommandations suggèrent de désactiver par défaut l'algorithme de Nagle, ce qui peut être fait dans le cadre d'applications spécifiques en définissant l'option TCP_NODELAY pour les sockets réseau à l'aide de l'appel à setsockopt, une pratique déjà adoptée dans des projets tels que Node.js et curl.
L'algorithme de Nagle permet d'agréger de petits messages pour réduire le trafic — il suspend l'envoi de nouveaux segments TCP jusqu'à réception d'un accusé de réception des données précédemment envoyées. Par exemple, sans l'agrégation, l'envoi de 1 octet entraîne l'envoi supplémentaire de 40 octets avec les en-têtes TCP et IP du paquet. Dans les conditions modernes, l'utilisation de l'algorithme de Nagle entraîne une augmentation significative des délais, inacceptables pour les applications interactives et distribuées.
On présente trois arguments principaux en faveur de l'utilisation par défaut de l'option TCP_NODELAY, qui désactive l'algorithme de Nagle :
- Incompatibilité de l'algorithme de Nagle avec l'optimisation « delayed ACK », où l'accusé de réception (ACK) n'est pas envoyé immédiatement, mais après la réception des données de réponse. Le problème est que, dans l'algorithme de Nagle, la réception du paquet ACK constitue un signal pour l'envoi des données agrégées, et si le paquet ACK n'est pas reçu, l'envoi se fait au bout d'un délai d'attente. Cela entraîne donc un cercle vicieux, où le paquet ACK n'agit pas comme un signal, car l'autre partie ne reçoit pas les données à cause de leur accumulation du côté de l'expéditeur, et l'expéditeur ne les envoie pas avant le délai d'attente, car il ne reçoit pas le paquet ACK.
- La RFC pour l'algorithme de Nagle a été adoptée en 1984 et elle n'est pas adaptée aux caractéristiques des réseaux à haute vitesse modernes et serveurs des centres de données, ce qui entraîne des problèmes de réactivité. Le délai entre l'envoi d'une requête et la réception d'une réponse (RTT) dans les réseaux modernes est de 0,5 ms + quelques millisecondes lors des échanges de données entre les centres de données d'une même région + jusqu'à une centaine de millisecondes pour les envois à l'échelle mondiale. En ces quelques millisecondes, un serveur moderne est capable d'accomplir une vaste quantité de travail.
- Les applications distribuées modernes n'envoient plus de simples octets de données ; l'agrégation de petites données est généralement réalisée au niveau de l'application. Même si la taille des données utiles se compte en octets, la taille réelle des informations envoyées augmente considérablement généralement après l'application de la sérialisation, l'utilisation d'API en JSON et l'envoi en utilisant le chiffrement TLS. Faire des économies de 40 octets devient alors moins pertinent.
Source : opennet.ru
