Marc Brooker, ingegnere di Amazon Web Services (AWS), ha esaminato le idee sbagliate riguardanti l'efficienza della trasmissione dei piccoli messaggi utilizzando l'algoritmo di Nagle, impiegato per impostazione predefinita nello stack TCP/IP. Le raccomandazioni suggeriscono di disattivare per default l'algoritmo di Nagle, il che può essere fatto, nel contesto di alcune applicazioni, impostando l'opzione TCP_NODELAY per i socket di rete tramite la chiamata a setsockopt, una pratica già adottata in progetti come Node.js e curl.
L'algoritmo di Nagle consente di aggregare piccoli messaggi per ridurre il traffico: sospende l'invio di nuovi segmenti TCP fino a ricevere conferma dell'accettazione dei dati precedentemente inviati. Ad esempio, senza aggregazione, l'invio di 1 byte comporta l'invio di ulteriori 40 byte con le intestazioni del pacchetto TCP e IP. Oggi, l'uso dell'algoritmo di Nagle porta a ritardi significativi, inaccettabili per applicazioni interattive e distribuite.
Sono presentati tre principali argomenti a favore dell'utilizzo dell'opzione TCP_NODELAY per impostazione predefinita, che disattiva l'algoritmo di Nagle:
- Incompatibilità dell'algoritmo di Nagle con l'ottimizzazione "delayed ACK", in cui la risposta ACK non viene inviata immediatamente, ma dopo aver ricevuto dati di risposta. Il problema è che nell'algoritmo di Nagle la ricezione del pacchetto ACK è un segnale per l'invio dei dati aggregati, mentre se il pacchetto ACK non arriva, l'invio avviene solo dopo un timeout. Si crea così un circolo vizioso in cui il pacchetto ACK come segnale non funziona, poiché l'altra parte non riceve i dati a causa dell'accumulo da parte dell'emittente, e l'emittente non li invia fino al timeout, poiché non riceve il pacchetto ACK.
- Lo standard RFC per l'algoritmo di Nagle è stato adottato nel 1984 e non è progettato per le caratteristiche delle moderne reti ad alta velocità e server nei datacenter, il che porta a problemi di reattività. Il tempo di latenza tra l'invio di una richiesta e la ricezione di una risposta (RTT) nelle reti moderne è di 0.5 ms più alcuni millisecondi per lo scambio di dati tra datacenter nella stessa regione e fino a centinaia di millisecondi per invii a livello globale. In questi millisecondi, un server moderno è in grado di svolgere un'enorme quantità di lavoro.
- Le moderne applicazioni distribuite non inviano più singoli byte di dati, e l'aggregazione di piccoli dati è generalmente realizzata a livello di applicazione. Anche se la dimensione dei dati utili è di pochi byte, per lo più la dimensione effettiva delle informazioni inviate aumenta significativamente dopo l'applicazione della serializzazione, l'uso di API in JSON e l'invio tramite crittografia TLS. Il risparmio di 40 byte diventa quindi meno rilevante.
Fonte: opennet.ru
