El protocol QUIC en acció: com el va implementar Uber per optimitzar el rendiment

El protocol QUIC és molt interessant de veure, per això ens encanta escriure sobre ell. Però si les publicacions anteriors sobre QUIC eren més de naturalesa històrica (història local, si voleu) i maquinari, avui ens complau publicar una traducció d'un altre tipus: parlarem de l'aplicació real del protocol el 2019. A més, no estem parlant de petites infraestructures basades en l'anomenat garatge, sinó d'Uber, que opera a gairebé tot el món. Com els enginyers de l'empresa van prendre la decisió d'utilitzar QUIC a la producció, com van dur a terme les proves i què van veure després de llançar-lo en producció, per sota del tall.

Les imatges es poden fer clic. Gaudeix de la lectura!

El protocol QUIC en acció: com el va implementar Uber per optimitzar el rendiment

Uber té una escala global, és a dir, 600 ciutats de presència, en cadascuna de les quals l'aplicació es basa completament en Internet sense fil de més de 4500 operadors de telefonia mòbil. Els usuaris esperen que l'aplicació no només sigui ràpida, sinó que sigui en temps real; per aconseguir-ho, l'aplicació Uber necessita una latència baixa i una connexió molt fiable. Ai, però la pila HTTP / 2 no funciona bé en xarxes sense fil dinàmiques i propenses a pèrdues. Ens vam adonar que en aquest cas, el baix rendiment està directament relacionat amb les implementacions de TCP als nuclis del sistema operatiu.

Per resoldre el problema, hem aplicat QUIC, un modern protocol de multiplexació de canals que ens ofereix més control sobre el rendiment del protocol de transport. Actualment el grup de treball IETF estandarditza QUIC com HTTP / 3.

Després de proves exhaustives, vam concloure que la implementació de QUIC a la nostra aplicació donaria lloc a latències de cua més baixes en comparació amb TCP. Vam observar una reducció del rang del 10 al 30% per al trànsit HTTPS a les aplicacions de conductor i passatgers. QUIC també ens va donar un control d'extrem a extrem sobre els paquets d'usuari.

En aquest article, compartim la nostra experiència en l'optimització de TCP per a aplicacions d'Uber mitjançant una pila que admet QUIC.

L'última tecnologia: TCP

Avui dia, TCP és el protocol de transport més utilitzat per lliurar trànsit HTTPS a Internet. TCP proporciona un flux fiable de bytes, fent front a la congestió de la xarxa i a les pèrdues de capa d'enllaç. L'ús generalitzat de TCP per al trànsit HTTPS es deu a la ubiqüitat del primer (gairebé tots els sistemes operatius conté TCP), la disponibilitat a la majoria d'infraestructures (com ara equilibradors de càrrega, servidors intermediaris HTTPS i CDN) i la funcionalitat disponible. a gairebé la majoria de plataformes i xarxes.

La majoria dels usuaris utilitzen la nostra aplicació en moviment, i les latències de cua TCP no s'apropaven a les demandes del nostre trànsit HTTPS en temps real. En poques paraules, usuaris de tot el món han experimentat això: la figura 1 mostra els retards a les principals ciutats:

El protocol QUIC en acció: com el va implementar Uber per optimitzar el rendiment
Figura 1: la latència de la cua varia entre les principals ciutats d'Uber.

Tot i que la latència a les xarxes índies i brasileres va ser més alta que als EUA i el Regne Unit, la latència de cua és significativament superior a la latència mitjana. I això és cert fins i tot per als EUA i el Regne Unit.

Rendiment TCP sobre l'aire

TCP es va crear per per cable xarxes, és a dir, amb èmfasi en enllaços altament predictibles. Malgrat això, sense fil les xarxes tenen les seves pròpies característiques i dificultats. En primer lloc, les xarxes sense fil són susceptibles a pèrdues a causa de la interferència i l'atenuació del senyal. Per exemple, les xarxes Wi-Fi són sensibles a microones, bluetooth i altres ones de ràdio. Les xarxes cel·lulars pateixen pèrdua de senyal (camí perdut) a causa de la reflexió/absorció del senyal per part d'objectes i edificis, així com de interferència del veí torres cel·lulars. Això porta a més significatius (4-10 vegades) i més diversos retard d'anada i tornada (RTT) i pèrdua de paquets en comparació amb una connexió per cable.

Per combatre les fluctuacions i les pèrdues de l'ample de banda, les xarxes cel·lulars solen utilitzar buffers grans per a les ràfegues de trànsit. Això pot provocar cues excessives, cosa que significa retards més llargs. Molt sovint, TCP tracta aquesta cua com un malbaratament a causa d'un temps d'espera prolongat, de manera que TCP tendeix a retransmetre i, per tant, omplir la memòria intermèdia. Aquest problema es coneix com bufferbloat (memòria intermèdia excessiva de la xarxa, inflor de memòria intermèdia), i això és molt problema greu Internet modern.

Finalment, el rendiment de la xarxa mòbil varia segons l'operador, la regió i l'hora. A la figura 2, vam recollir els retards mitjans del trànsit HTTPS a través de les cel·les dins d'un rang de 2 quilòmetres. Dades recollides per a dos principals operadors de telefonia mòbil a Delhi, Índia. Com podeu veure, el rendiment varia d'una cel·la a una altra. A més, la productivitat d'un operador difereix de la productivitat del segon. Això està influenciat per factors com els patrons d'entrada a la xarxa tenint en compte el temps i la ubicació, la mobilitat dels usuaris, així com la infraestructura de la xarxa tenint en compte la densitat de la torre i la proporció de tipus de xarxa (LTE, 3G, etc.).

El protocol QUIC en acció: com el va implementar Uber per optimitzar el rendiment
Figura 2. Retardes utilitzant com a exemple un radi de 2 km. Delhi, Índia.

A més, el rendiment de les xarxes mòbils varia amb el temps. La figura 3 mostra la latència mitjana per dia de la setmana. També vam observar diferències a menor escala, en un sol dia i hora.

El protocol QUIC en acció: com el va implementar Uber per optimitzar el rendiment
Figura 3. Els retards de la cua poden variar significativament entre dies, però per al mateix operador.

Tot això fa que el rendiment TCP sigui ineficaç a les xarxes sense fil. Tanmateix, abans de buscar alternatives a TCP, volíem desenvolupar una comprensió precisa dels punts següents:

  • TCP és el principal culpable de les latències de cua a les nostres aplicacions?
  • Les xarxes modernes tenen retards d'anada i tornada (RTT) significatius i variats?
  • Quin és l'impacte de la RTT i la pèrdua en el rendiment de TCP?

Anàlisi de rendiment de TCP

Per entendre com hem analitzat el rendiment de TCP, fem una ullada ràpida a com el TCP transfereix dades d'un remitent a un receptor. En primer lloc, el remitent estableix una connexió TCP, realitzant una connexió de tres vies encaixada de mans: El remitent envia un paquet SYN, espera un paquet SYN-ACK del receptor i després envia un paquet ACK. Es gasta una segona i tercera passada addicional per establir la connexió TCP. El destinatari reconeix la recepció de cada paquet (ACK) per garantir un lliurament fiable.

Si es perd un paquet o un ACK, el remitent retransmet després d'un temps d'espera (RTO, temps d'espera de retransmissió). El RTO es calcula dinàmicament en funció de diversos factors, com ara el retard RTT esperat entre l'emissor i el destinatari.

El protocol QUIC en acció: com el va implementar Uber per optimitzar el rendiment
Figura 4. L'intercanvi de paquets per TCP/TLS inclou un mecanisme de retransmissió.

Per determinar com funcionava el TCP a les nostres aplicacions, vam supervisar els paquets TCP mitjançant tcpdump durant una setmana al trànsit de combat provinent dels servidors de punta indis. Després vam analitzar les connexions TCP utilitzant tcptrace. A més, hem creat una aplicació per a Android que envia trànsit emulat a un servidor de prova, imitant el trànsit real tant com sigui possible. Els telèfons intel·ligents amb aquesta aplicació es van distribuir a diversos empleats, que van recollir registres durant diversos dies.

Els resultats d'ambdós experiments van ser coherents entre si. Vam veure altes latències RTT; els valors de la cua eren gairebé 6 vegades més alts que el valor mitjà; la mitjana aritmètica dels retards és superior a 1 segon. Moltes connexions tenien pèrdues, fet que va fer que TCP retransmetia el 3,5% de tots els paquets. A zones congestionades com aeroports i estacions de tren, vam veure pèrdues del 7%. Aquests resultats posen en dubte la saviesa convencional que s'utilitzen a les xarxes cel·lulars circuits de retransmissió avançats reduir significativament les pèrdues a nivell de transport. A continuació es mostren els resultats de la prova de l'aplicació "simulador":

Mètriques de xarxa
Els valors

RTT, mil·lisegons [50%,75%, 95%,99%]
[350, 425, 725, 2300]

Divergència RTT, segons
De mitjana ~1,2 s

Pèrdua de paquets en connexions inestables
Mitjana ~3.5% (7% en zones sobrecarregades)

Gairebé la meitat d'aquestes connexions van tenir almenys una pèrdua de paquets, la majoria paquets SYN i SYN-ACK. La majoria de les implementacions TCP utilitzen un valor RTO d'1 segon per als paquets SYN, que augmenta exponencialment per a les pèrdues posteriors. Els temps de càrrega de les aplicacions poden augmentar perquè TCP triga més a establir connexions.

En el cas dels paquets de dades, els alts valors de RTO redueixen molt la utilització útil de la xarxa en presència de pèrdues transitòries a les xarxes sense fil. Hem trobat que el temps mitjà de retransmissió és d'aproximadament 1 segon amb un retard de cua de gairebé 30 segons. Aquestes altes latències a nivell de TCP van provocar temps d'espera i re-sol·licituds HTTPS, augmentant encara més la latència i la ineficiència de la xarxa.

Mentre que el percentil 75 de RTT mesurat era d'uns 425 ms, el percentil 75 de TCP era de gairebé 3 segons. Això indica que la pèrdua va fer que TCP trigués entre 7 i 10 passades per transmetre dades amb èxit. Això pot ser una conseqüència d'un càlcul ineficient de RTO, la incapacitat de TCP per respondre ràpidament a la pèrdua paquets més recents a la finestra i la ineficiència de l'algoritme de control de congestió, que no distingeix entre pèrdues sense fil i pèrdues per congestió de la xarxa. A continuació es mostren els resultats de les proves de pèrdua de TCP:

Estadístiques de pèrdua de paquets TCP
Valor

Percentatge de connexions amb almenys 1 pèrdua de paquet
45%

Percentatge de connexions amb pèrdues durant la configuració de la connexió
30%

Percentatge de connexions amb pèrdues durant l'intercanvi de dades
76%

Distribució dels retards en la retransmissió, segons [50%, 75%, 95%,99%] [1, 2.8, 15, 28]

Distribució del nombre de retransmissions per a un paquet o segment TCP
[1,3,6,7]

Aplicació de QUIC

Desenvolupat originalment per Google, QUIC és un protocol de transport modern multifil que s'executa a la part superior d'UDP. Actualment hi ha QUIC procés d'estandardització (ja vam escriure que hi ha, per dir-ho, dues versions de QUIC, curioses pot seguir l'enllaç – aprox. traductor). Com es mostra a la figura 5, QUIC es col·loca sota HTTP/3 (de fet, HTTP/2 a sobre de QUIC és HTTP/3, que ara s'està estandarditzant de manera intensiva). Substitueix parcialment les capes HTTPS i TCP utilitzant UDP per formar paquets. QUIC només admet la transferència de dades segura, ja que TLS està totalment integrat a QUIC.

El protocol QUIC en acció: com el va implementar Uber per optimitzar el rendiment
Figura 5: QUIC s'executa amb HTTP/3, substituint TLS, que abans s'executava amb HTTP/2.

A continuació es mostren les raons que ens van convèncer d'utilitzar QUIC per a l'amplificació TCP:

  • Establiment de connexió 0-RTT. QUIC permet la reutilització d'autoritzacions de connexions anteriors, reduint el nombre de cops de mà de seguretat. En el futur TLS1.3 admetrà 0-RTT, però encara serà necessari un encaix de mà TCP de tres vies.
  • superant el bloqueig HoL. HTTP/2 utilitza una connexió TCP per client per millorar el rendiment, però això pot provocar un bloqueig de HoL (cap de línia). QUIC simplifica la multiplexació i lliura sol·licituds a l'aplicació de manera independent.
  • control de la congestió. QUIC resideix a la capa d'aplicació, facilitant l'actualització de l'algoritme de transport principal que controla l'enviament en funció de paràmetres de xarxa (nombre de pèrdues o RTT). La majoria de les implementacions TCP utilitzen l'algoritme CÚBIC, que no és òptim per al trànsit sensible a la latència. Algorismes desenvolupats recentment com Extensió BB, modelar amb més precisió la xarxa i optimitzar la latència. QUIC us permet utilitzar BBR i actualitzar aquest algorisme a mesura que s'utilitza. millorant.
  • reposició de pèrdues. QUIC crida a dos TLP (sonda de pèrdua de cua) abans que s'activi el RTO, fins i tot quan les pèrdues són molt notables. Això és diferent de les implementacions TCP. TLP retransmet principalment l'últim paquet (o el nou, si n'hi ha) per activar una reposició ràpida. La gestió dels retards de cua és especialment útil per a la forma en què Uber opera la seva xarxa, és a dir, per a transferències de dades curtes, esporàdiques i sensibles a la latència.
  • ACK optimitzat. Com que cada paquet té un número de seqüència únic, no hi ha cap problema distincions paquets quan es retransmeten. Els paquets ACK també contenen temps per processar el paquet i generar un ACK al costat del client. Aquestes funcions garanteixen que QUIC calculi RTT amb més precisió. ACK a QUIC admet fins a 256 bandes NACK, ajudant al remitent a ser més resistent a la barreja de paquets i a utilitzar menys bytes en el procés. ACK selectiu (SAC) en TCP no resol aquest problema en tots els casos.
  • migració de connexió. Les connexions QUIC s'identifiquen mitjançant un identificador de 64 bits, de manera que si un client canvia les adreces IP, l'identificador de connexió anterior es pot continuar utilitzant a la nova adreça IP sense interrupcions. Aquesta és una pràctica molt comuna per a aplicacions mòbils on l'usuari canvia entre connexions Wi-Fi i cel·lulars.

Alternatives a QUIC

Hem considerat enfocaments alternatius per resoldre el problema abans de triar QUIC.

El primer que vam intentar va ser desplegar TPC PoP (Punts de presència) per acabar les connexions TCP més a prop dels usuaris. Essencialment, els PoP finalitzen una connexió TCP amb un dispositiu mòbil més a prop de la xarxa mòbil i envia el trànsit a la infraestructura original. Si tanquem el TCP més a prop, podem reduir potencialment l'RTT i assegurar-nos que el TCP respon més a un entorn sense fil dinàmic. Tanmateix, els nostres experiments han demostrat que la major part de l'RTT i la pèrdua prové de xarxes cel·lulars i l'ús de PoPs no proporciona una millora significativa del rendiment.

També vam analitzar l'ajust dels paràmetres TCP. Configurar una pila TCP als nostres servidors perifèrics heterogenis va ser difícil perquè TCP té implementacions dispars en diferents versions del sistema operatiu. Va ser difícil implementar-ho i provar diferents configuracions de xarxa. No va ser possible configurar TCP directament als dispositius mòbils per manca de permisos. Més important encara, característiques com les connexions 0-RTT i la predicció RTT millorada són crítiques per a l'arquitectura del protocol i, per tant, és impossible aconseguir beneficis significatius ajustant només TCP.

Finalment, vam avaluar diversos protocols basats en UDP que solucionen problemes de transmissió de vídeo; volíem veure si aquests protocols podrien ajudar en el nostre cas. Malauradament, mancaven greument molts paràmetres de seguretat i també requerien una connexió TCP addicional per a les metadades i la informació de control.

La nostra investigació ha demostrat que QUIC és potser l'únic protocol que pot ajudar amb el problema del trànsit d'Internet, tot tenint en compte tant la seguretat com el rendiment.

Integració de QUIC a la plataforma

Per integrar QUIC amb èxit i millorar el rendiment de les aplicacions en entorns de connectivitat deficient, hem substituït la pila antiga (HTTP/2 sobre TLS/TCP) pel protocol QUIC. Hem utilitzat la biblioteca de xarxa Cronet d' Projectes Chromium, que conté la versió original de Google del protocol: gQUIC. Aquesta implementació també es millora constantment per seguir l'última especificació de l'IETF.

Primer vam integrar Cronet a les nostres aplicacions d'Android per afegir compatibilitat amb QUIC. La integració es va dur a terme de manera que es reduïssin al màxim els costos de migració. En lloc de substituir completament l'antiga pila de xarxa que utilitzava la biblioteca D'acord Http, hem integrat Cronet SOTA el marc de l'API OkHttp. En fer la integració d'aquesta manera, hem evitat canvis a les nostres trucades de xarxa (que són utilitzades per Reformar) a nivell d'API.

De manera similar a l'enfocament per als dispositius Android, vam implementar Cronet a les aplicacions d'Uber a iOS, interceptant el trànsit HTTP de la xarxa. APIutilitzant NSURLProtocol. Aquesta abstracció, proporcionada per la Fundació iOS, gestiona les dades d'URL específiques del protocol i assegura que podem integrar Cronet a les nostres aplicacions iOS sense costos de migració significatius.

Completant QUIC a Google Cloud Balancers

Al costat del backend, la finalització QUIC la proporciona la infraestructura d'equilibri de càrrega de Google Cloud, que utilitza alt-svc capçaleres en respostes per donar suport a QUIC. En general, l'equilibrador afegeix una capçalera alt-svc a cada sol·licitud HTTP, i això ja valida el suport QUIC per al domini. Quan un client de Cronet rep una resposta HTTP amb aquesta capçalera, utilitza QUIC per a les sol·licituds HTTP posteriors a aquest domini. Un cop l'equilibrador completa el QUIC, la nostra infraestructura envia explícitament aquesta acció mitjançant HTTP2/TCP als nostres centres de dades.

Rendiment: resultats

El rendiment de la sortida és el principal motiu de la nostra recerca d'un protocol millor. Per començar, hem creat un estand amb emulació de xarxaper saber com es comportarà QUIC sota diferents perfils de xarxa. Per provar el rendiment de QUIC a les xarxes del món real, vam fer experiments mentre conduïm per Nova Delhi utilitzant trànsit de xarxa emulat molt semblant a les trucades HTTP a l'aplicació de passatgers.

Experiment 1

Equip per a l'experiment:

  • prova els dispositius Android amb piles OkHttp i Cronet per assegurar-nos que permetem el trànsit HTTPS per TCP i QUIC respectivament;
  • un servidor d'emulació basat en Java que envia el mateix tipus de capçaleres HTTPS a les respostes i carrega dispositius client per rebre sol·licituds d'ells;
  • servidors intermediaris de núvol que es troben físicament a prop de l'Índia per acabar les connexions TCP i QUIC. Mentre que per a la terminació de TCP vam utilitzar un servidor intermediari invers NGINX, va ser difícil trobar un servidor intermediari invers de codi obert per a QUIC. Hem creat un servidor intermediari invers per a QUIC mitjançant la pila bàsica de QUIC de Chromium i publicat en crom com a codi obert.

El protocol QUIC en acció: com el va implementar Uber per optimitzar el rendimentEl protocol QUIC en acció: com el va implementar Uber per optimitzar el rendiment
Figura 6. La suite de proves de carretera TCP vs QUIC constava de dispositius Android amb OkHttp i Cronet, servidors intermediaris de núvol per finalitzar connexions i un servidor d'emulació.

Experiment 2

Quan Google va posar QUIC disponible amb Equilibri de càrrega de Google Cloud, vam utilitzar el mateix inventari, però amb una modificació: en comptes de NGINX, vam agafar equilibradors de càrrega de Google per finalitzar les connexions TCP i QUIC dels dispositius, així com per encaminar el trànsit HTTPS al servidor d'emulació. Els equilibradors es distribueixen per tot el món, però utilitzen el servidor PoP més proper al dispositiu (gràcies a la geolocalització).

El protocol QUIC en acció: com el va implementar Uber per optimitzar el rendiment
Figura 7. En el segon experiment, hem volgut comparar la latència de finalització de TCP i QUIC: utilitzant Google Cloud i utilitzant el nostre servidor intermediari de núvol.

Com a resultat, ens esperaven diverses revelacions:

  • la terminació mitjançant PoP ha millorat el rendiment de TCP. Atès que els equilibradors acaben les connexions TCP més a prop dels usuaris i estan molt optimitzats, això provoca uns RTT més baixos, la qual cosa millora el rendiment de TCP. I tot i que QUIC es va veure menys afectat, encara va superar el TCP en termes de reducció de la latència de la cua (entre un 10 i un 30 per cent).
  • les cues es veuen afectades salts de xarxa. Tot i que el nostre servidor intermediari QUIC estava més lluny dels dispositius (uns 50 ms de latència més gran) que els equilibradors de càrrega de Google, va oferir un rendiment similar: una reducció del 15% de la latència enfront d'una reducció del 20% del percentil 99 per a TCP. Això suggereix que la transició de l'última milla és un coll d'ampolla a la xarxa.

El protocol QUIC en acció: com el va implementar Uber per optimitzar el rendimentEl protocol QUIC en acció: com el va implementar Uber per optimitzar el rendiment
Figura 8: Els resultats de dos experiments mostren que QUIC supera significativament el TCP.

Combatre el trànsit

Inspirats per l'experimentació, hem implementat el suport QUIC a les nostres aplicacions per a Android i iOS. Hem realitzat proves A/B per determinar l'impacte del QUIC a les ciutats on opera Uber. En general, vam observar una reducció significativa dels retards de cua a les dues regions, operadors de telecomunicacions i tipus de xarxa.

Els gràfics següents mostren les millores percentuals de les cues (percentils 95 i 99) per macroregió i diferents tipus de xarxa: LTE, 3G, 2G.
El protocol QUIC en acció: com el va implementar Uber per optimitzar el rendimentEl protocol QUIC en acció: com el va implementar Uber per optimitzar el rendiment
Figura 9. A les proves de batalla, QUIC va superar TCP en termes de latència.

Reenvia només

Potser això és només el començament: el llançament de QUIC en producció ha proporcionat oportunitats sorprenents per millorar el rendiment de les aplicacions tant en xarxes estables com inestables, a saber:

Augment de la cobertura

Després d'haver analitzat el rendiment del protocol en trànsit real, vam veure que aproximadament el 80% de les sessions utilitzaven amb èxit QUIC per Tot sol·licituds, mentre que el 15% de les sessions utilitzaven una combinació de QUIC i TCP. Suposem que la combinació es deu al temps d'espera de la biblioteca de Cronet que torna a TCP, ja que no pot distingir entre errors UDP reals i condicions de xarxa pobres. Actualment estem buscant una solució a aquest problema mentre treballem per a la posterior implementació de QUIC.

Optimització QUIC

El trànsit de les aplicacions mòbils és sensible a la latència, però no a l'ample de banda. A més, les nostres aplicacions s'utilitzen principalment en xarxes mòbils. Segons els experiments, les latències de cua encara són altes tot i que s'utilitza un servidor intermediari per finalitzar TCP i QUIC a prop dels usuaris. Estem buscant activament maneres de millorar la gestió de la congestió i millorar l'eficiència dels algorismes de recuperació de pèrdues QUIC.

Amb aquestes i moltes altres millores, tenim previst millorar l'experiència de l'usuari independentment de la xarxa i la regió, fent que el transport de paquets còmode i fluid sigui més accessible a tot el món.

Font: www.habr.com

Afegeix comentari