Marc Brooker, inginer la Amazon Web Services (AWS), a discutat despre miturile legate de îmbunătățirea eficienței transmisiei de mesaje mici utilizând algoritmul Nagle, care este aplicat implicit în stiva TCP/IP. Recomandările se concentrează pe dezactivarea algoritmului Nagle în mod implicit, ceea ce, în contextul aplicațiilor individuale, se poate realiza prin setarea opțiunii TCP_NODELAY pentru socket-uri de rețea folosind apelul setsockopt, argumente care sunt deja utilizate în proiecte precum Node.js și curl.
Algoritmul Nagle permite agregarea mesajelor mici pentru a reduce traficul — suspendă trimiterea de noi segmente TCP până la primirea unui confirmare a faptului că datele trimise anterior au fost recepționate. De exemplu, fără utilizarea agregării, atunci când trimitem 1 byte, se adaugă suplimentar 40 de bytes cu antetele pachetelor TCP și IP. În condițiile moderne, utilizarea algoritmului Nagle duce la o creștere semnificativă a întârzierilor, inacceptabile pentru aplicațiile interactive și distribuite.
Se prezintă trei argumente principale în favoarea utilizării opțiunii TCP_NODELAY, care dezactivează algoritmul Nagle:
- Incompatibilitatea algoritmului Nagle cu optimizarea „delayed ACK”, în care răspunsul ACK nu este trimis imediat, ci după ce se primesc datele de răspuns. Problema constă în faptul că, în algoritmul Nagle, primirea pachetului ACK este un semnal pentru trimiterea datelor agregate, iar dacă pachetul ACK nu a fost primit, trimiterea se va realiza la expirarea timpului de așteptare. Astfel, apare un cerc vicios, iar pachetul ACK ca semnal nu funcționează, deoarece cealaltă parte nu primește date din cauza acumulării acestora de partea expeditorului, iar expeditorul nu le trimite până la expirarea timpului de așteptare, deoarece nu primește pachetul ACK.
- RFC pentru algoritmul Nagle a fost adoptat în 1984 și nu este adaptat pentru parametrii rețelelor moderne de înaltă viteză și servere centrele de date, ceea ce duce la probleme de reacție. Întârzierea dintre trimiterea unei cereri și primirea unui răspuns (RTT) în rețelele moderne este de 0,5 ms + câteva milisecunde în timpul schimbului de date între centrele de date din aceeași regiune + până la o sută de milisecunde la transmiterea în întreaga lume. În aceste milisecunde, un server modern poate realiza un volum uriaș de muncă.
- Aplicațiile distribuite moderne nu mai trimit date în byte-uri individuale, iar agregarea datelor minuscule se implementează de obicei la nivel de aplicație. Chiar dacă mărimea datelor utile este de câțiva byte, de regulă dimensiunea informației trimise crește semnificativ după aplicarea serializării, utilizarea API-urilor în JSON și trimiterea cu criptare TLS. Economisirea a 40 byte devine mai puțin relevantă.
Sursa: opennet.ro
