Poprawa wydajności TCP w sieci gigabitowej z dużą liczbą połączeń i dużym ruchem małych pakietów

37

Próbuję poprawić moją przepustowość TCP w „gigabitowej sieci z dużą ilością połączeń i dużym ruchem małych pakietów”. Mój system operacyjny serwera to Ubuntu 11.10 Server 64bit.

Istnieje około 50 000 (i rosnących) klientów podłączonych do mojego serwera za pośrednictwem gniazd TCP (wszystkie na tym samym porcie).

95% moich pakietów ma rozmiar 1-150 bajtów (nagłówek TCP i ładunek). Pozostałe 5% waha się od 150 do 4096+ bajtów.

Dzięki poniższej konfiguracji mój serwer może obsłużyć ruch do 30 Mb / s (pełny dupleks).

Czy możesz doradzić najlepszą praktykę, aby dostosować system operacyjny do moich potrzeb?

Mój /etc/sysctl.congwygląda tak:

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

Oto moje ograniczenia:

$ 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

[DODANY]

Moje karty sieciowe są następujące:

$ 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

[DODANO 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

[DODANO 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

Kilka informacji o SACK: kiedy wyłączyć TCP SACK?

Pracownik
źródło
Co jest czynnikiem ograniczającym? Czy Twój procesor się wyczerpał? Jeśli tak, to szczekasz na niewłaściwe drzewo. Musisz spojrzeć na to, co robi procesor.
David Schwartz,
Jaką masz kartę sieciową?
SaveTheRbtz
1
BTW: Dlaczego wyłączasz SACK?
Nils
1
Powinieneś ponownie rozważyć użycie Broadcom NICs ...
Hubert Kario

Odpowiedzi:

21

Problem może polegać na tym, że na karcie sieciowej występuje zbyt wiele przerwań. Jeśli przepustowość nie jest problemem, problemem jest częstotliwość:

  • Włącz bufory wysyłania / odbierania na karcie sieciowej

    ethtool -g eth0
    

Pokaże bieżące ustawienia (256 lub 512 wpisów). Prawdopodobnie możesz je podnieść do 1024, 2048 lub 3172. Więcej prawdopodobnie nie ma sensu. To tylko bufor pierścieniowy, który zapełnia się tylko wtedy, gdy serwer nie jest w stanie przetworzyć przychodzących pakietów wystarczająco szybko.

Jeśli bufor zacznie się zapełniać, kontrola przepływu jest dodatkowym sposobem poinformowania routera lub przełączenia na spowolnienie:

  • Włącz kontrolę przepływu przychodzącą / wychodzącą na serwerze oraz porty przełącznika / routera, do których jest podłączony.

    ethtool -a eth0
    

Prawdopodobnie pokaże:

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

Sprawdź / var / log / messages dla aktualnego ustawienia eth0. Sprawdź coś takiego:

eth0: Łącze działa z prędkością 1000 Mb / s, pełny dupleks, kontrola przepływu tx i rx

Jeśli nie widzisz tx i rx, administratorzy sieci muszą dostosować wartości na przełączniku / routerze. W Cisco, w którym włączona jest kontrola przepływu odbioru / transmisji.

Uwaga: zmiana tych wartości spowoduje obniżenie i zwiększenie twojego łącza na bardzo krótki czas (mniej niż 1s).

  • Jeśli to wszystko nie pomoże - możesz także obniżyć prędkość karty sieciowej do 100 MBit (zrób to samo na portach przełącznika / routera)

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

Ale w twoim przypadku powiedziałbym - podnieś bufory odbiorcze w buforze pierścieniowym karty sieciowej.

Nils
źródło
Patrząc na twoje liczby ethtool, powiedziałbym - ustaw bufory odbiorcze karty sieciowej na maksimum, aby uniknąć odrzucania RX. Mam nadzieję, że twój Broadcom ma ich dość.
Nils,
1
Zwiększenie buforowania za pomocą TCP prawie nigdy nie jest dobrym pomysłem. Mamy już za dużo buforowania: bufferbloat.net/projects/bloat/wiki/Introduction
rmalayter
3
Bufor ten jest buforem sprzętowym bezpośrednio w karcie sieciowej. Zaktualizuję swoją odpowiedź o więcej szczegółów. Ponieważ tracisz przychodzące pakiety, potrzebujesz tego bufora. Mam podobny serwer, na którym musiałem przełączyć się na inną kartę sieciową (z wbudowanego Broadcomu na PCIe Intel), aby móc zwiększyć te bufory. Potem już nigdy nie spotkałem utraconych pakietów RX.
Nils,
@malayter: jest to bufor pierścieniowy na warstwie 2. Zobacz moją zaktualizowaną odpowiedź.
Nils
1
Wreszcie mamy 1 GB. Było wiele tuningu w różnych miejscach, więc naprawdę nie mogę powiedzieć, że był jeden problem.
Pracownik
5

Poniższe może nie być ostateczną odpowiedzią, ale na pewno przedstawi pewne pomysły

Spróbuj dodać je do 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

Chociaż selektywne tcp ack jest dobre dla optymalnej wydajności w przypadku sieci o dużej przepustowości. Uważaj jednak na inne wady . Zalety skalowania okien opisano tutaj . Jeśli chodzi o trzecią opcję sysctl: domyślnie TCP zapisuje różne metryki połączenia w pamięci podręcznej tras po zamknięciu połączenia, dzięki czemu połączenia ustanowione w najbliższej przyszłości mogą je wykorzystać do ustawienia warunków początkowych. Zwykle zwiększa to ogólną wydajność, ale czasami może powodować spadek wydajności. Jeśli jest ustawiony, TCP nie będzie buforował metryk przy zamykaniu połączeń.

Sprawdź z

ethtool -k ethX

aby sprawdzić, czy odciążanie jest włączone, czy nie. Odciążanie sumy kontrolnej TCP i odciążanie dużych segmentów jest obsługiwane przez większość współczesnych kart sieciowych Ethernet i najwyraźniej Broadcom również to obsługuje.

Spróbuj użyć narzędzia

powertop

gdy sieć jest bezczynna i kiedy osiągnięte jest nasycenie sieci. To na pewno pokaże, czy winowajcą są przerwania NIC. Odpytywanie urządzenia jest odpowiedzią na taką sytuację. FreeBsd obsługuje przełącznik odpytywania bezpośrednio w ifconfig, ale Linux nie ma takiej opcji. Sprawdź to, aby włączyć odpytywanie. Mówi, że BroadCom obsługuje również odpytywanie, co jest dla Ciebie dobrą wiadomością.

Ulepszenie pakietu Jumbo może nie być dla Ciebie odpowiednie, ponieważ wspomniałeś, że ruch składa się głównie z małych pakietów. Ale hej i tak wypróbuj!

kaji
źródło
2kaji, spróbuję jutro sugestie. O PowerTop - czy powinienem dostroić oszczędzanie energii, jeśli moim celem jest wydajność?
Robotnik
Tak, oczywiście, że może to również pomóc. Wspomniałem o powertopie, aby upewnić się, czy przeszkody są złe. Częstotliwość przerwań można również zebrać z innych narzędzi
kaji
Widzę wysokie „Przerywane przerwy” - czy to może być powód? Co to jest „Przestawianie przerwań”?
Robotnik
Spróbuj wykonać to ---> help.ubuntu.com/community/ReschedulingInterrupts
kaji
tak .. Widziałem ten samouczek, ale dotyczy laptopów, podczas gdy widzę duże przerwy w serwerze. Spróbuje zastosować go na serwerze.
Robotnik
2

musisz rozłożyć obciążenie na wszystkie rdzenie procesora. Uruchom „brak równowagi”.

użytkownik175978
źródło
1
Nie pomoże to, jeśli pojedyncze IRQ ma bardzo wysoką częstotliwość. IRQBalance próbuje dystrybuować pojedyncze IRQ do odpowiednich procesorów logicznych - ale nigdy nie będzie więcej niż jeden procesor obsługujący jedno IRQ.
Nils
2

Na liście poprawek zauważyłem, że znaczniki czasu są wyłączone, nie rób tego. Jest to stary powrót do dawnych czasów, gdy przepustowość była naprawdę droga i ludzie chcieli zaoszczędzić kilka bajtów / pakiet. Jest on używany na przykład przez stos TCP w dzisiejszych czasach, aby stwierdzić, czy pakiet przychodzący do gniazda w „CLOSE_WAIT” jest starym pakietem dla połączenia, czy też jest nowym pakietem dla nowego połączenia i pomaga w obliczeniach RTT. A zapisanie kilku bajtów dla znacznika czasu NIC nie jest w porównaniu z tym, co dodają adresy IPv6. Wyłączenie znaczników czasu powoduje więcej szkody niż pożytku.

To zalecenie dotyczące wyłączania znaczników czasu jest tylko cofnięciem, które przechodzi z jednej generacji sysadmin do następnej. Coś w rodzaju „miejskiej legendy”.

GeorgeB
źródło
2

Proponuję to:

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

Testowane na serwerach Oracle DB na RHEL i oprogramowaniu do tworzenia kopii zapasowych.

Konrad Puchała
źródło
5
Liczby te można konfigurować, ponieważ nie ma jednego uniwersalnego rozwiązania. Oznacza to, że same liczby nie są cenne. To, co może być cenne, to metoda, której użyłeś, aby zdecydować, jakich liczb użyć.
kasperd
2

W moim przypadku tylko jeden tuning:

net.ipv4.tcp_timestamps = 0

dokonał bardzo dużej i użytecznej zmiany, czas ładowania witryny zmniejszył się o 50%.

avz2012
źródło
Aby tak się stało, coś musi zostać poważnie uszkodzone w twojej konfiguracji. Znaczniki czasu zużywają mniej niż 1% przepustowości w normalnych okolicznościach i pozwolą TCP wykonywać retransmisje o wiele bardziej ściśle czasowo niż w innym przypadku.
kasperd