Miglioramento delle prestazioni TCP su una rete gigabit con molte connessioni e traffico elevato di piccoli pacchetti


37

Sto cercando di migliorare il mio throughput TCP su una "rete gigabit con molte connessioni e traffico elevato di piccoli pacchetti". Il mio sistema operativo server è Ubuntu 11.10 Server 64 bit.

Ci sono circa 50.000 (e in crescita) client connessi al mio server tramite socket TCP (tutti sulla stessa porta).

Il 95% dei miei pacchetti ha dimensioni di 1-150 byte (intestazione TCP e payload). Il resto del 5% varia da 150 a 4096+ byte.

Con la configurazione di seguito il mio server è in grado di gestire il traffico fino a 30 Mbps (full duplex).

Potete per favore consigliare le migliori pratiche per ottimizzare il sistema operativo in base alle mie esigenze?

Il mio /etc/sysctl.congassomiglia a questo:

kernel.pid_max = 1000000
net.ipv4.ip_local_port_range = 2500 65000
fs.file-max = 1000000
#
net.core.netdev_max_backlog=3000
net.ipv4.tcp_sack=0
#
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.somaxconn = 2048
#
net.ipv4.tcp_rmem = 4096 87380 16777216 
net.ipv4.tcp_wmem = 4096 65536 16777216
#
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_mem = 50576   64768   98152
#
net.core.wmem_default = 65536
net.core.rmem_default = 65536
net.ipv4.tcp_window_scaling=1
#
net.ipv4.tcp_mem= 98304 131072 196608
#
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_rfc1337 = 1
net.ipv4.ip_forward = 0
net.ipv4.tcp_congestion_control=cubic
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
#
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192

Ecco i miei limiti:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 193045
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1000000
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1000000

[AGGIUNTO]

Le mie schede di rete sono le seguenti:

$ dmesg | grep Broad
[    2.473081] Broadcom NetXtreme II 5771x 10Gigabit Ethernet Driver bnx2x 1.62.12-0 (2011/03/20)
[    2.477808] bnx2x 0000:02:00.0: eth0: Broadcom NetXtreme II BCM57711E XGb (A0) PCI-E x4 5GHz (Gen2) found at mem fb000000, IRQ 28, node addr d8:d3:85:bd:23:08
[    2.482556] bnx2x 0000:02:00.1: eth1: Broadcom NetXtreme II BCM57711E XGb (A0) PCI-E x4 5GHz (Gen2) found at mem fa000000, IRQ 40, node addr d8:d3:85:bd:23:0c

[AGGIUNTO 2]

ethtool -k eth0
Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: on
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off
receive-hashing: off

[AGGIUNTO 3]

 sudo ethtool -S eth0|grep -vw 0
 NIC statistics:
      [1]: rx_bytes: 17521104292
      [1]: rx_ucast_packets: 118326392
      [1]: tx_bytes: 35351475694
      [1]: tx_ucast_packets: 191723897
      [2]: rx_bytes: 16569945203
      [2]: rx_ucast_packets: 114055437
      [2]: tx_bytes: 36748975961
      [2]: tx_ucast_packets: 194800859
      [3]: rx_bytes: 16222309010
      [3]: rx_ucast_packets: 109397802
      [3]: tx_bytes: 36034786682
      [3]: tx_ucast_packets: 198238209
      [4]: rx_bytes: 14884911384
      [4]: rx_ucast_packets: 104081414
      [4]: rx_discards: 5828
      [4]: rx_csum_offload_errors: 1
      [4]: tx_bytes: 35663361789
      [4]: tx_ucast_packets: 194024824
      [5]: rx_bytes: 16465075461
      [5]: rx_ucast_packets: 110637200
      [5]: tx_bytes: 43720432434
      [5]: tx_ucast_packets: 202041894
      [6]: rx_bytes: 16788706505
      [6]: rx_ucast_packets: 113123182
      [6]: tx_bytes: 38443961940
      [6]: tx_ucast_packets: 202415075
      [7]: rx_bytes: 16287423304
      [7]: rx_ucast_packets: 110369475
      [7]: rx_csum_offload_errors: 1
      [7]: tx_bytes: 35104168638
      [7]: tx_ucast_packets: 184905201
      [8]: rx_bytes: 12689721791
      [8]: rx_ucast_packets: 87616037
      [8]: rx_discards: 2638
      [8]: tx_bytes: 36133395431
      [8]: tx_ucast_packets: 196547264
      [9]: rx_bytes: 15007548011
      [9]: rx_ucast_packets: 98183525
      [9]: rx_csum_offload_errors: 1
      [9]: tx_bytes: 34871314517
      [9]: tx_ucast_packets: 188532637
      [9]: tx_mcast_packets: 12
      [10]: rx_bytes: 12112044826
      [10]: rx_ucast_packets: 84335465
      [10]: rx_discards: 2494
      [10]: tx_bytes: 36562151913
      [10]: tx_ucast_packets: 195658548
      [11]: rx_bytes: 12873153712
      [11]: rx_ucast_packets: 89305791
      [11]: rx_discards: 2990
      [11]: tx_bytes: 36348541675
      [11]: tx_ucast_packets: 194155226
      [12]: rx_bytes: 12768100958
      [12]: rx_ucast_packets: 89350917
      [12]: rx_discards: 2667
      [12]: tx_bytes: 35730240389
      [12]: tx_ucast_packets: 192254480
      [13]: rx_bytes: 14533227468
      [13]: rx_ucast_packets: 98139795
      [13]: tx_bytes: 35954232494
      [13]: tx_ucast_packets: 194573612
      [13]: tx_bcast_packets: 2
      [14]: rx_bytes: 13258647069
      [14]: rx_ucast_packets: 92856762
      [14]: rx_discards: 3509
      [14]: rx_csum_offload_errors: 1
      [14]: tx_bytes: 35663586641
      [14]: tx_ucast_packets: 189661305
      rx_bytes: 226125043936
      rx_ucast_packets: 1536428109
      rx_bcast_packets: 351
      rx_discards: 20126
      rx_filtered_packets: 8694
      rx_csum_offload_errors: 11
      tx_bytes: 548442367057
      tx_ucast_packets: 2915571846
      tx_mcast_packets: 12
      tx_bcast_packets: 2
      tx_64_byte_packets: 35417154
      tx_65_to_127_byte_packets: 2006984660
      tx_128_to_255_byte_packets: 373733514
      tx_256_to_511_byte_packets: 378121090
      tx_512_to_1023_byte_packets: 77643490
      tx_1024_to_1522_byte_packets: 43669214
      tx_pause_frames: 228

Alcune informazioni su SACK: quando disattivare TCP SACK?


1
Questo può essere d'aiuto: datatag.web.cern.ch/datatag/howto/tcp.html
yrk

Qual è il fattore limitante? La tua CPU si esaurisce al massimo? Se è così, stai abbaiando sull'albero sbagliato. Devi guardare cosa sta facendo la CPU.
David Schwartz,

Che NIC hai?
SaveTheRbtz

1
A proposito: perché disattivi SACK?
Nils,

1
Dovresti riconsiderare l'utilizzo delle schede di rete Broadcom ...
Hubert Kario,

Risposte:


21

Il problema potrebbe essere che stai ricevendo troppi interrupt sulla tua scheda di rete. Se la larghezza di banda non è il problema, la frequenza è il problema:

  • Attiva i buffer di invio / ricezione sulla scheda di rete

    ethtool -g eth0
    

Ti mostrerà le impostazioni correnti (256 o 512 voci). Probabilmente puoi aumentarli a 1024, 2048 o 3172. Più probabilmente non ha senso. Questo è solo un buffer ad anello che si riempie solo se il server non è in grado di elaborare i pacchetti in entrata abbastanza velocemente.

Se il buffer inizia a riempirsi, il controllo del flusso è un ulteriore mezzo per dire al router o passare al rallentamento:

  • Attiva / disattiva il controllo del flusso sul server e sulle porte switch / router a cui è collegato.

    ethtool -a eth0
    

Probabilmente mostrerà:

Pause parameters for eth0:
Autonegotiate:  on
RX:             on
TX:             on

Controllare / var / log / messaggi per l'impostazione corrente di eth0. Controlla qualcosa come:

eth0: il collegamento è attivo a 1000 Mbps, full duplex, controllo di flusso tx e rx

Se non vedi tx e rx, gli amministratori di rete devono regolare i valori sullo switch / router. Su Cisco che è il controllo del flusso di ricezione / trasmissione attivo.

Attenzione: la modifica di questi valori porterà il collegamento verso l'alto e verso il basso per un tempo molto breve (meno di 1 secondo).

  • Se tutto ciò non aiuta, puoi anche abbassare la velocità della scheda di rete a 100 MBit (fai lo stesso sulle porte switch / router)

    ethtool -s eth0 autoneg off && ethtool -s eth0 speed 100
    

Ma nel tuo caso direi: aumentare i buffer di ricezione nel buffer dell'anello NIC.


Guardando i tuoi numeri da ethtooldirei: imposta i buffer di ricezione della scheda di rete al massimo per evitare gli scarti RX. Spero che la tua Broadcom ne abbia abbastanza.
Nils,

1
Aumentare il buffering con TCP non è quasi mai una buona idea. Abbiamo già troppi buffering: bufferbloat.net/projects/bloat/wiki/Introduction
rmalayter

3
Questo buffer è un buffer hardware direttamente sulla scheda NIC. Aggiornerò la mia risposta con maggiori dettagli. Dato che stai perdendo i pacchetti in entrata, hai bisogno di quel buffer. Ho un server simile in cui ho dovuto passare a una scheda di rete diversa (da Broadcom onboard a PCIe Intel) per poter aumentare questi buffer. Dopo di che non ho più incontrato pacchetti RX persi.
Nils,

@malayter: questo è un ring-buffer sul livello 2. Vedi la mia risposta aggiornata.
Nils,

1
Finalmente abbiamo 1 GB. Ci sono state molte regolazioni in luoghi diversi, quindi non posso davvero dire che ci fosse un singolo problema.
Lavoratore,

5

Di seguito potrebbe non essere la risposta definitiva, ma sicuramente presenterà alcune idee

Prova ad aggiungere questi a sysctl.conf

##  tcp selective acknowledgements. 
net.ipv4.tcp_sack = 1
##enable window scaling
net.ipv4.tcp_window_scaling = 1
##
net.ipv4.tcp_no_metrics_save = 1

Mentre il tcp ack selettivo è buono per prestazioni ottimali in caso di rete ad alta larghezza di banda. Ma attenzione agli altri inconvenienti . I vantaggi del ridimensionamento delle finestre sono descritti qui . Come per la terza opzione sysctl: per impostazione predefinita, TCP salva varie metriche di connessione nella cache del percorso quando la connessione viene chiusa, in modo che le connessioni stabilite nel prossimo futuro possano utilizzarle per impostare le condizioni iniziali. Di solito, ciò aumenta le prestazioni complessive, ma a volte può causare un peggioramento delle prestazioni. Se impostato, TCP non memorizzerà nella cache le metriche sulla chiusura delle connessioni.

Controllare con

ethtool -k ethX

per vedere se l'offload è abilitato o meno. Offload di checksum TCP e offload di grandi segmenti sono supportati dalla maggior parte delle schede di rete Ethernet di oggi e apparentemente Broadcom lo supporta.

Prova a usare lo strumento

powertop

mentre la rete è inattiva e quando viene raggiunta la saturazione della rete. Ciò mostrerà sicuramente se gli interruttori della NIC sono i colpevoli. Il polling del dispositivo è una risposta a tale situazione. FreeBsd supporta lo switch di polling all'interno di ifconfig ma Linux non ha questa opzione. Consultare questo per abilitare il polling. Sta dicendo che BroadCom supporta anche il polling, che è una buona notizia per te.

La modifica dei pacchetti Jumbo potrebbe non tagliarti per te poiché hai menzionato che il tuo traffico è costituito principalmente da piccoli pacchetti. Ma hey provalo comunque!


2kaji, domani proverò suggerimenti. Informazioni su PowerTop: devo ottimizzare il risparmio energetico se il mio obiettivo è la prestazione?
Lavoratore,

Sì, certo, potrebbe anche aiutare. Ho citato powertop solo per assicurarmi che gli interrupt siano il male. La frequenza delle interruzioni potrebbe anche essere raccolta da altri strumenti
kaji,

Vedo "Riprogrammazione interruzioni" elevate - potrebbe essere un motivo? Che cos'è "Ripianificazione interruzioni"?
Lavoratore,


sì .. ho visto quel tutorial, ma è per i laptop mentre vedo interruzioni elevate nel server. Proverà ad applicarlo al server.
Lavoratore,

2

è necessario distribuire il carico su tutti i core della CPU. Inizia 'irqbalance'.


1
Questo non aiuterà se un singolo IRQ ha una freuency molto alta. IRQBalance tenta di distribuire singoli IRQ ai processori logici adatti, ma non ci sarà mai più di un processore che serve un singolo IRQ.
Nils,

2

Ho notato nell'elenco delle modifiche che i timestamp sono disattivati, per favore non farlo. Questo è un vecchio ritorno ai tempi in cui la larghezza di banda era davvero costosa e la gente voleva risparmiare qualche byte / pacchetto. In questi giorni viene utilizzato, ad esempio, dallo stack TCP per sapere se un pacchetto che arriva per un socket in "CLOSE_WAIT" è un vecchio pacchetto per la connessione o se è un nuovo pacchetto per una nuova connessione e aiuta nei calcoli RTT. E salvare i pochi byte per un timestamp non è NULLA rispetto agli indirizzi IPv6 che verranno aggiunti. Disattivare i timestamp fa più male che bene.

Questa raccomandazione per disattivare i timestamp è solo un ritorno al passato che continua a passare da una generazione di amministratore di sistema a quella successiva. Una specie di "leggenda urbana".


2

Propongo questo:

kernel.sem = 350 358400 64 1024
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 4194304
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_adv_win_scale = 2
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_rmem = 4096 262144 4194304
net.ipv4.tcp_wmem = 4096 262144 4194304
net.ipv4.tcp_keepalive_time = 900
net.ipv4.tcp_keepalive_intvl = 900
net.ipv4.tcp_keepalive_probes = 9

Testato nei server Oracle DB su RHEL e nel software di backup.


5
Questi numeri sono configurabili perché non esiste una taglia unica. Ciò significa che i numeri stessi non sono preziosi. Ciò che potrebbe essere prezioso è il metodo che hai usato per decidere quali numeri usare.
Kasperd,

2

Nel mio caso solo un singolo tuninng:

net.ipv4.tcp_timestamps = 0

fatto una modifica molto grande e utile, il tempo di caricamento del sito è diminuito del 50%.


Qualcosa deve essere gravemente rotto nella tua configurazione affinché ciò accada. I timestamp utilizzano meno dell'1% della larghezza di banda in circostanze normali e consentiranno a TCP di eseguire ritrasmissioni con tempi molto più rigorosi rispetto a quelli altrimenti.
Kasperd,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.