Le protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performances

Le protocole QUIC est extrêmement intéressant à observer, c’est pourquoi nous aimons écrire à son sujet. Mais si les publications précédentes sur QUIC étaient plutôt de nature historique (histoire locale, si vous préférez) et matérielle, nous sommes heureux de publier aujourd'hui une traduction d'un genre différent - nous parlerons de l'application réelle du protocole en 2019. De plus, nous ne parlons pas d’une petite infrastructure basée dans un soi-disant garage, mais d’Uber, qui opère presque partout dans le monde. Comment les ingénieurs de l'entreprise ont pris la décision d'utiliser QUIC en production, comment ils ont effectué les tests et ce qu'ils ont vu après son déploiement en production - en dessous de la limite.

Les images sont cliquables. Bonne lecture!

Le protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performances

Uber a une envergure mondiale, à savoir 600 villes de présence, dans chacune desquelles l'application s'appuie entièrement sur l'Internet sans fil de plus de 4500 XNUMX opérateurs cellulaires. Les utilisateurs s'attendent à ce que l'application soit non seulement rapide, mais aussi en temps réel. Pour y parvenir, l'application Uber a besoin d'une faible latence et d'une connexion très fiable. Hélas, mais la pile HTTP / 2 ne fonctionne pas bien dans les réseaux sans fil dynamiques et sujets aux pertes. Nous avons réalisé que dans ce cas, les faibles performances sont directement liées à l'implémentation de TCP dans les noyaux du système d'exploitation.

Pour résoudre le problème, nous avons appliqué QUIC, un protocole de multiplexage de canaux moderne qui nous donne plus de contrôle sur les performances du protocole de transport. Actuellement, le groupe de travail IETF normalise QUIC comme HTTP / 3.

Après des tests approfondis, nous avons conclu que la mise en œuvre de QUIC dans notre application entraînerait des latences de queue inférieures à celles de TCP. Nous avons observé une réduction de l’ordre de 10 à 30 % du trafic HTTPS dans les applications conducteur et passager. QUIC nous a également donné un contrôle de bout en bout sur les packages utilisateur.

Dans cet article, nous partageons notre expérience dans l'optimisation de TCP pour les applications Uber à l'aide d'une pile prenant en charge QUIC.

La dernière technologie : TCP

Aujourd'hui, TCP est le protocole de transport le plus utilisé pour acheminer le trafic HTTPS sur Internet. TCP fournit un flux d'octets fiable, faisant ainsi face à la congestion du réseau et aux pertes de couche de liaison. L'utilisation généralisée de TCP pour le trafic HTTPS est due à l'omniprésence du premier (presque tous les systèmes d'exploitation contiennent TCP), à la disponibilité sur la plupart des infrastructures (telles que les équilibreurs de charge, les proxys HTTPS et les CDN) et aux fonctionnalités prêtes à l'emploi disponibles. sur presque la plupart des plateformes et réseaux.

La plupart des utilisateurs utilisent notre application en déplacement, et les latences de queue TCP étaient loin de répondre aux exigences de notre trafic HTTPS en temps réel. En termes simples, les utilisateurs du monde entier en ont fait l'expérience. La figure 1 montre les retards dans les grandes villes :

Le protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performances
Figure 1 : La latence de queue varie selon les principales villes d'Uber.

Bien que la latence sur les réseaux indiens et brésiliens soit plus élevée qu'aux États-Unis et au Royaume-Uni, la latence de queue est nettement supérieure à la latence moyenne. Et cela est vrai même aux États-Unis et au Royaume-Uni.

Performances TCP en direct

TCP a été créé pour filaire réseaux, c’est-à-dire en mettant l’accent sur des liens hautement prévisibles. Cependant, sans fil Les réseaux ont leurs propres caractéristiques et difficultés. Premièrement, les réseaux sans fil sont sensibles aux pertes dues aux interférences et à l’atténuation du signal. Par exemple, les réseaux Wi-Fi sont sensibles aux micro-ondes, au Bluetooth et à d’autres ondes radio. Les réseaux cellulaires souffrent de perte de signal (chemin perdu) en raison de la réflexion/absorption du signal par les objets et les bâtiments, ainsi que par ingérence du voisin tours de téléphonie cellulaire. Cela conduit à des résultats plus importants (4 à 10 fois) et plus diversifiés. Temps d'aller-retour (RTT) et la perte de paquets par rapport à une connexion filaire.

Pour lutter contre les fluctuations et les pertes de bande passante, les réseaux cellulaires utilisent généralement de grandes mémoires tampon pour les rafales de trafic. Cela peut entraîner des files d’attente excessives, ce qui signifie des délais plus longs. Très souvent, TCP traite cette file d'attente comme un gaspillage en raison d'un délai d'attente prolongé, donc TCP a tendance à relayer et ainsi à remplir le tampon. Ce problème est connu sous le nom ballonnement tampon (mise en mémoire tampon réseau excessive, gonflement de la mémoire tampon), et c'est très Problème sérieux Internet moderne.

Enfin, les performances du réseau cellulaire varient selon l'opérateur, la région et l'heure. Dans la figure 2, nous avons collecté les délais médians du trafic HTTPS entre les cellules dans un rayon de 2 kilomètres. Données collectées pour deux principaux opérateurs de téléphonie mobile à Delhi, en Inde. Comme vous pouvez le constater, les performances varient d’une cellule à l’autre. De plus, la productivité d'un opérateur diffère de la productivité du second. Ceci est influencé par des facteurs tels que les modèles d'entrée dans le réseau prenant en compte l'heure et le lieu, la mobilité des utilisateurs, ainsi que l'infrastructure réseau prenant en compte la densité des tours et le ratio des types de réseaux (LTE, 3G, etc.).

Le protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performances
Figure 2. Retards en utilisant un rayon de 2 km comme exemple. Delhi, Inde.

De plus, les performances des réseaux cellulaires varient dans le temps. La figure 3 montre la latence médiane par jour de la semaine. Nous avons également observé des différences à plus petite échelle, au sein d’une même journée et d’une même heure.

Le protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performances
Figure 3. Les retards peuvent varier considérablement d'un jour à l'autre, mais pour le même opérateur.

Tout ce qui précède rend les performances TCP inefficaces dans les réseaux sans fil. Cependant, avant de chercher des alternatives au TCP, nous avons souhaité développer une compréhension précise sur les points suivants :

  • TCP est-il le principal responsable des latences de queue dans nos applications ?
  • Les réseaux modernes présentent-ils des délais aller-retour (RTT) importants et variés ?
  • Quel est l’impact du RTT et de la perte sur les performances TCP ?

Analyse des performances TCP

Pour comprendre comment nous avons analysé les performances de TCP, examinons rapidement comment TCP transfère les données d'un expéditeur à un destinataire. Tout d'abord, l'expéditeur établit une connexion TCP, effectuant une communication à trois poignée de main: L'expéditeur envoie un paquet SYN, attend un paquet SYN-ACK du récepteur, puis envoie un paquet ACK. Une deuxième et une troisième passe supplémentaires sont consacrées à l'établissement de la connexion TCP. Le destinataire accuse réception de chaque paquet (ACK) pour garantir une livraison fiable.

Si un paquet ou un ACK est perdu, l'expéditeur retransmet après un délai d'attente (RTO, délai de retransmission). Le RTO est calculé dynamiquement en fonction de divers facteurs, tels que le délai RTT attendu entre l'expéditeur et le destinataire.

Le protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performances
Figure 4. L'échange de paquets sur TCP/TLS inclut un mécanisme de retransmission.

Pour déterminer les performances de TCP dans nos applications, nous avons surveillé les paquets TCP à l'aide de tcpdump pendant une semaine sur le trafic de combat provenant des serveurs Edge indiens. Nous avons ensuite analysé les connexions TCP en utilisant tracer. De plus, nous avons créé une application Android qui envoie du trafic émulé à un serveur de test, imitant autant que possible le trafic réel. Des smartphones équipés de cette application ont été distribués à plusieurs collaborateurs, qui ont collecté les logs sur plusieurs jours.

Les résultats des deux expériences étaient cohérents les uns avec les autres. Nous avons constaté des latences RTT élevées ; les valeurs extrêmes étaient presque 6 fois supérieures à la valeur médiane ; la moyenne arithmétique des retards est supérieure à 1 seconde. De nombreuses connexions étaient avec perte, ce qui obligeait TCP à retransmettre 3,5 % de tous les paquets. Dans les zones encombrées comme les aéroports et les gares, nous avons constaté des pertes de 7 %. Ces résultats remettent en question l'idée reçue selon laquelle ceux utilisés dans les réseaux cellulaires circuits de retransmission avancés réduire considérablement les pertes au niveau du transport. Ci-dessous les résultats des tests de l'application « simulateur » :

Métriques du réseau
Les valeurs

RTT, millisecondes [50 %, 75 %, 95 %, 99 %]
[350, 425, 725, 2300]

Divergence RTT, secondes
En moyenne ~1,2 s

Perte de paquets sur des connexions instables
Moyenne ~3.5% (7% dans les zones surchargées)

Près de la moitié de ces connexions ont subi au moins une perte de paquet, la plupart étant des paquets SYN et SYN-ACK. La plupart des implémentations TCP utilisent une valeur RTO de 1 seconde pour les paquets SYN, qui augmente de façon exponentielle en cas de pertes ultérieures. Les temps de chargement des applications peuvent augmenter car TCP met plus de temps à établir les connexions.

Dans le cas des paquets de données, des valeurs RTO élevées réduisent considérablement l'utilisation utile du réseau en présence de pertes transitoires dans les réseaux sans fil. Nous avons constaté que le temps moyen de retransmission est d'environ 1 seconde avec un retard de près de 30 secondes. Ces latences élevées au niveau TCP ont provoqué des délais d'attente et des nouvelles requêtes HTTPS, augmentant encore la latence et l'inefficacité du réseau.

Alors que le 75e centile du RTT mesuré était d'environ 425 ms, le 75e centile du TCP était de près de 3 secondes. Cela laisse entendre que la perte a amené TCP à effectuer 7 à 10 passes pour transmettre avec succès les données. Cela peut être une conséquence d'un calcul RTO inefficace, de l'incapacité de TCP à répondre rapidement aux pertes. derniers forfaits dans la fenêtre et l'inefficacité de l'algorithme de contrôle de congestion, qui ne fait pas de distinction entre les pertes sans fil et les pertes dues à la congestion du réseau. Vous trouverez ci-dessous les résultats des tests de perte TCP :

Statistiques de perte de paquets TCP
Valeur

Pourcentage de connexions avec au moins 1 perte de paquet
45%

Pourcentage de connexions avec pertes lors de l'établissement de la connexion
30%

Pourcentage de connexions avec pertes lors de l'échange de données
76%

Répartition des délais de retransmission, secondes [50 %, 75 %, 95 %, 99 %] [1, 2.8, 15, 28]

Répartition du nombre de retransmissions pour un paquet ou un segment TCP

Application de QUIC

Développé à l'origine par Google, QUIC est un protocole de transport moderne multithread qui s'exécute sur UDP. Actuellement, QUIC est en processus de normalisation (nous avons déjà écrit qu'il existe en quelque sorte deux versions de QUIC, curieux je peux suivre le lien - environ. traducteur). Comme le montre la figure 5, QUIC est placé sous HTTP/3 (en fait, HTTP/2 au-dessus de QUIC est HTTP/3, qui fait actuellement l'objet d'une normalisation intensive). Il remplace partiellement les couches HTTPS et TCP en utilisant UDP pour former des paquets. QUIC ne prend en charge que le transfert de données sécurisé car TLS est entièrement intégré à QUIC.

Le protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performances
Figure 5 : QUIC s'exécute sous HTTP/3, remplaçant TLS, qui s'exécutait auparavant sous HTTP/2.

Voici les raisons qui nous ont convaincu d’utiliser QUIC pour l’amplification TCP :

  • Établissement de la connexion 0-RTT. QUIC permet la réutilisation des autorisations des connexions précédentes, réduisant ainsi le nombre de poignées de main de sécurité. Dans le futur TLS1.3 prendra en charge 0-RTT, mais une négociation TCP à trois voies sera toujours requise.
  • surmonter le blocage HoL. HTTP/2 utilise une connexion TCP par client pour améliorer les performances, mais cela peut conduire à un blocage HoL (tête de ligne). QUIC simplifie le multiplexage et transmet les requêtes à l'application de manière indépendante.
  • contrôle des embouteillages. QUIC réside au niveau de la couche application, ce qui facilite la mise à jour de l'algorithme de transport principal qui contrôle l'envoi en fonction des paramètres du réseau (nombre de pertes ou RTT). La plupart des implémentations TCP utilisent l'algorithme CUBIQUE, ce qui n'est pas optimal pour le trafic sensible à la latence. Des algorithmes récemment développés comme BBR, modélisez plus précisément le réseau et optimisez la latence. QUIC vous permet d'utiliser BBR et de mettre à jour cet algorithme au fur et à mesure de son utilisation. amélioration.
  • reconstitution des pertes. QUIC appelle deux TLP (sonde de perte de queue) avant le déclenchement du RTO - même lorsque les pertes sont très perceptibles. Ceci est différent des implémentations TCP. TLP retransmet principalement le dernier paquet (ou le nouveau, s'il y en a un) pour déclencher un réapprovisionnement rapide. La gestion des retards est particulièrement utile pour la manière dont Uber exploite son réseau, notamment pour les transferts de données courts, sporadiques et sensibles à la latence.
  • ACK optimisé. Puisque chaque paquet possède un numéro de séquence unique, il n’y a aucun problème distinctions paquets lors de leur retransmission. Les paquets ACK contiennent également du temps pour traiter le paquet et générer un ACK côté client. Ces fonctionnalités garantissent que QUIC calcule le RTT avec plus de précision. ACK dans QUIC prend en charge jusqu'à 256 bandes NACK, aidant l'expéditeur à être plus résilient au brassage des paquets et à utiliser moins d'octets dans le processus. ACK sélectif (SAC) dans TCP ne résout pas ce problème dans tous les cas.
  • migration de connexion. Les connexions QUIC sont identifiées par un ID de 64 bits, donc si un client change d'adresse IP, l'ancien ID de connexion peut continuer à être utilisé sur la nouvelle adresse IP sans interruption. Il s'agit d'une pratique très courante pour les applications mobiles où l'utilisateur bascule entre les connexions Wi-Fi et cellulaires.

Alternatives à QUIC

Nous avons envisagé des approches alternatives pour résoudre le problème avant de choisir QUIC.

La première chose que nous avons essayée a été de déployer des PoP (Points de présence) TPC pour terminer les connexions TCP plus près des utilisateurs. Essentiellement, les PoP mettent fin à une connexion TCP avec un appareil mobile plus proche du réseau cellulaire et renvoient le trafic vers l'infrastructure d'origine. En terminant TCP plus près, nous pouvons potentiellement réduire le RTT et garantir que TCP soit plus réactif à un environnement sans fil dynamique. Cependant, nos expériences ont montré que la majeure partie du RTT et des pertes proviennent des réseaux cellulaires et que l’utilisation de PoP n’apporte pas d’amélioration significative des performances.

Nous avons également examiné le réglage des paramètres TCP. La configuration d'une pile TCP sur nos serveurs périphériques hétérogènes était difficile car TCP a des implémentations disparates selon les différentes versions de système d'exploitation. Il était difficile de mettre en œuvre cela et de tester différentes configurations réseau. La configuration de TCP directement sur les appareils mobiles n'était pas possible en raison du manque d'autorisations. Plus important encore, des fonctionnalités telles que les connexions 0-RTT et la prédiction RTT améliorée sont essentielles à l'architecture du protocole et il est donc impossible d'obtenir des avantages significatifs en réglant uniquement TCP.

Enfin, nous avons évalué plusieurs protocoles basés sur UDP permettant de résoudre les problèmes de streaming vidéo. Nous voulions voir si ces protocoles seraient utiles dans notre cas. Malheureusement, ils manquaient cruellement de nombreux paramètres de sécurité et nécessitaient également une connexion TCP supplémentaire pour les métadonnées et les informations de contrôle.

Nos recherches ont montré que QUIC est peut-être le seul protocole capable de résoudre le problème du trafic Internet, tout en prenant en compte à la fois la sécurité et les performances.

Intégration de QUIC dans la plateforme

Pour intégrer avec succès QUIC et améliorer les performances des applications dans des environnements de connectivité médiocre, nous avons remplacé l'ancienne pile (HTTP/2 sur TLS/TCP) par le protocole QUIC. Nous avons utilisé la bibliothèque réseau Cronet de Projets Chrome, qui contient la version originale de Google du protocole - gQUIC. Cette implémentation est également constamment améliorée pour suivre la dernière spécification de l'IETF.

Nous avons d'abord intégré Cronet dans nos applications Android pour ajouter la prise en charge de QUIC. L'intégration a été réalisée de manière à réduire autant que possible les coûts de migration. Au lieu de remplacer complètement l'ancienne pile réseau qui utilisait la bibliothèque OkHttp, nous avons intégré Cronet SOUS le framework API OkHttp. En procédant à l'intégration de cette façon, nous avons évité de modifier nos appels réseau (qui sont utilisés par Rénovation) au niveau de l'API.

Semblable à l'approche adoptée pour les appareils Android, nous avons implémenté Cronet dans les applications Uber sur iOS, interceptant le trafic HTTP du réseau. APIUtilisation Protocole NSURL. Cette abstraction, fournie par la Fondation iOS, gère les données URL spécifiques au protocole et garantit que nous pouvons intégrer Cronet dans nos applications iOS sans coûts de migration importants.

Compléter QUIC sur les Google Cloud Balancers

Côté backend, la complétion QUIC est assurée par l'infrastructure d'équilibrage de charge Google Cloud, qui utilise alt-svc en-têtes dans les réponses pour prendre en charge QUIC. En général, l'équilibreur ajoute un en-tête alt-svc à chaque requête HTTP, ce qui valide déjà la prise en charge de QUIC pour le domaine. Lorsqu'un client Cronet reçoit une réponse HTTP avec cet en-tête, il utilise QUIC pour les requêtes HTTP ultérieures vers ce domaine. Une fois que l'équilibreur a terminé le QUIC, notre infrastructure envoie explicitement cette action via HTTP2/TCP à nos centres de données.

Performance : résultats

Les performances de sortie sont la principale raison de notre recherche d’un meilleur protocole. Pour commencer, nous avons créé un stand avec émulation de réseaupour savoir comment QUIC se comportera sous différents profils de réseau. Pour tester les performances de QUIC sur les réseaux du monde réel, nous avons mené des expériences en conduisant autour de New Delhi en utilisant un trafic réseau émulé très similaire aux appels HTTP dans l'application passagers.

expérience 1

Matériel pour l'expérience :

  • testez les appareils Android avec les piles OkHttp et Cronet pour vous assurer que nous autorisons le trafic HTTPS sur TCP et QUIC respectivement ;
  • un serveur d'émulation basé sur Java qui envoie le même type d'en-têtes HTTPS dans les réponses et charge les appareils clients pour recevoir des requêtes de leur part ;
  • des proxys cloud physiquement situés à proximité de l'Inde pour mettre fin aux connexions TCP et QUIC. Alors que pour la terminaison TCP, nous avons utilisé un proxy inverse sur Nginx, il était difficile de trouver un proxy inverse open source pour QUIC. Nous avons nous-mêmes construit un proxy inverse pour QUIC en utilisant la pile QUIC de base de Chromium et ont publié en chrome en open source.

Le protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performancesLe protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performances
Figure 6. La suite de tests routiers TCP vs QUIC comprenait des appareils Android avec OkHttp et Cronet, des proxys cloud pour mettre fin aux connexions et un serveur d'émulation.

expérience 2

Lorsque Google a rendu QUIC disponible avec Équilibrage de charge Google Cloud, nous avons utilisé le même inventaire, mais avec une modification : au lieu de NGINX, nous avons utilisé les équilibreurs de charge Google pour mettre fin aux connexions TCP et QUIC des appareils, ainsi que pour acheminer le trafic HTTPS vers le serveur d'émulation. Les Balancers sont distribués partout dans le monde, mais utilisent le serveur PoP le plus proche de l'appareil (grâce à la géolocalisation).

Le protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performances
Figure 7. Dans la deuxième expérience, nous voulions comparer la latence d'achèvement de TCP et QUIC : en utilisant Google Cloud et en utilisant notre proxy cloud.

De ce fait, plusieurs révélations nous attendaient :

  • la terminaison via PoP a amélioré les performances TCP. Étant donné que les équilibreurs terminent les connexions TCP plus près des utilisateurs et sont hautement optimisés, cela se traduit par des RTT plus faibles, ce qui améliore les performances TCP. Et même si QUIC a été moins affecté, il a tout de même surpassé TCP en termes de réduction de la latence de queue (de 10 à 30 %).
  • les queues sont affectées sauts de réseau. Bien que notre proxy QUIC soit plus éloigné des appareils (latence environ 50 ms plus élevée) que les équilibreurs de charge de Google, il a fourni des performances similaires : une réduction de 15 % de la latence contre une réduction de 20 % du 99e centile pour TCP. Cela suggère que la transition du dernier kilomètre constitue un goulot d’étranglement dans le réseau.

Le protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performancesLe protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performances
Figure 8 : Les résultats de deux expériences montrent que QUIC surpasse considérablement TCP.

Combattre le trafic

Inspirés par l'expérimentation, nous avons implémenté le support QUIC dans nos applications Android et iOS. Nous avons effectué des tests A/B pour déterminer l'impact de QUIC dans les villes où Uber opère. De manière générale, nous avons constaté une réduction significative des retards de queue dans les deux régions, opérateurs de télécommunications et types de réseaux.

Les graphiques ci-dessous montrent les améliorations en pourcentage des queues (95 et 99 centiles) par macro-région et différents types de réseaux : LTE, 3G, 2G.
Le protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performancesLe protocole QUIC en action : comment Uber l'a mis en œuvre pour optimiser les performances
Figure 9. Lors des tests de combat, QUIC a surpassé TCP en termes de latence.

Transférer seulement

Ce n'est peut-être qu'un début : la mise en production de QUIC a offert d'incroyables opportunités d'améliorer les performances des applications dans les réseaux stables et instables, à savoir :

Couverture accrue

Après avoir analysé les performances du protocole sur le trafic réel, nous avons constaté qu'environ 80 % des sessions utilisaient avec succès QUIC pour tous requêtes, tandis que 15 % des sessions utilisaient une combinaison de QUIC et TCP. Nous supposons que cette combinaison est due au délai d'attente de la bibliothèque Cronet vers TCP, car elle ne peut pas faire la distinction entre les échecs UDP réels et les mauvaises conditions du réseau. Nous recherchons actuellement une solution à ce problème alors que nous travaillons à la mise en œuvre ultérieure de QUIC.

Optimisation QUIC

Le trafic provenant des applications mobiles est sensible à la latence, mais pas à la bande passante. De plus, nos applications sont principalement utilisées sur les réseaux cellulaires. D'après les expériences, les latences de queue sont toujours élevées même si l'on utilise un proxy pour terminer TCP et QUIC à proximité des utilisateurs. Nous recherchons activement des moyens d'améliorer la gestion de la congestion et d'améliorer l'efficacité des algorithmes de récupération des pertes QUIC.

Grâce à ces améliorations et à plusieurs autres, nous prévoyons d’améliorer l’expérience utilisateur quels que soient le réseau et la région, rendant ainsi le transport de paquets pratique et transparent plus accessible dans le monde entier.

Source: habr.com

Ajouter un commentaire