Dysponujemy infrastrukturą w kilku głównych lokalizacjach na całym świecie - Singapurze, Londynie i Los Angeles. RTT pomiędzy dowolnymi dwoma lokalizacjami wynosi ponad> 150ms.
Niedawno zaktualizowaliśmy wszystkie serwery, aby korzystały z łączy 1 Gb / s (od 100 Mb / s). Przeprowadziliśmy kilka testów opartych na TCP między serwerami w różnych lokalizacjach i uzyskaliśmy zaskakujące wyniki. Te wyniki są całkowicie powtarzalne.
- Od Los Angeles (100 Mb / s) do Londynu (100 Mb / s): przepustowość ~ 96 Mb / s
- Z Los Angeles (100 Mb / s) do Londynu (1 Gb / s): przepustowość ~ 96 Mb / s
- Od Los Angeles (1 Gb / s) do Londynu (100 Mb / s): przepustowość 10-40 Mb / s (lotna)
- Od Los Angeles (1 Gb / s) do Londynu (1 Gb / s): przepustowość 10-40 Mb / s (lotna)
- Od Los Angeles (1 Gb / s) do Los Angeles (1 Gb / s): przepustowość> 900 Mb / s
Wygląda na to, że ilekroć nadawca działa z prędkością 1 Gb / s, nasza przepustowość znacznie spada z powodu długich łączy.
Wcześniejsze podejście do testowania jest niezwykle proste - po prostu używam cURL, aby pobrać plik binarny 1 GB z serwera docelowego (więc w powyższym przypadku klient cURL działa na serwerze w Londynie i pobiera z LA, więc LA jest nadawcą) . Oczywiście używa to jednego połączenia TCP.
Powtarzając te same testy przez UDP przy użyciu iperf, problem znika!
- Od Los Angeles (100 Mb / s) do Londynu (100 Mb / s): przepustowość ~ 96 Mb / s
- Z Los Angeles (100 Mb / s) do Londynu (1 Gb / s): przepustowość ~ 96 Mb / s
- Od Los Angeles (1 Gb / s) do Londynu (100 Mb / s): przepustowość ~ 96 Mb / s
- Od Los Angeles (1 Gb / s) do Londynu (1 Gb / s): przepustowość> 250 Mb / s
Wskazuje to wprost na problem z konfiguracją TCP lub NIC / portu w moich oczach.
Na obu serwerach działa CentOS 6.x, z sześciennym TCP. Oba mają maksymalnie 8 MB okien wysyłania i odbierania TCP oraz włączone znaczniki czasu TCP i selektywne potwierdzenia. Ta sama konfiguracja TCP jest używana we wszystkich przypadkach testowych. Pełna konfiguracja TCP znajduje się poniżej:
net.core.somaxconn = 128
net.core.xfrm_aevent_etime = 10
net.core.xfrm_aevent_rseqth = 2
net.core.xfrm_larval_drop = 1
net.core.xfrm_acq_expires = 30
net.core.wmem_max = 8388608
net.core.rmem_max = 8388608
net.core.wmem_default = 131072
net.core.rmem_default = 131072
net.core.dev_weight = 64
net.core.netdev_max_backlog = 1000
net.core.message_cost = 5
net.core.message_burst = 10
net.core.optmem_max = 20480
net.core.rps_sock_flow_entries = 0
net.core.netdev_budget = 300
net.core.warnings = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_retrans_collapse = 1
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_retries1 = 3
net.ipv4.tcp_retries2 = 15
net.ipv4.tcp_fin_timeout = 60
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_abort_on_overflow = 0
net.ipv4.tcp_stdurg = 0
net.ipv4.tcp_rfc1337 = 0
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_orphan_retries = 0
net.ipv4.tcp_fack = 1
net.ipv4.tcp_reordering = 3
net.ipv4.tcp_ecn = 2
net.ipv4.tcp_dsack = 1
net.ipv4.tcp_mem = 1528512 2038016 3057024
net.ipv4.tcp_wmem = 4096 131072 8388608
net.ipv4.tcp_rmem = 4096 131072 8388608
net.ipv4.tcp_app_win = 31
net.ipv4.tcp_adv_win_scale = 2
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_frto = 2
net.ipv4.tcp_frto_response = 0
net.ipv4.tcp_low_latency = 0
net.ipv4.tcp_no_metrics_save = 0
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_tso_win_divisor = 3
net.ipv4.tcp_congestion_control = cubic
net.ipv4.tcp_abc = 0
net.ipv4.tcp_mtu_probing = 0
net.ipv4.tcp_base_mss = 512
net.ipv4.tcp_workaround_signed_windows = 0
net.ipv4.tcp_dma_copybreak = 4096
net.ipv4.tcp_slow_start_after_idle = 1
net.ipv4.tcp_available_congestion_control = cubic reno
net.ipv4.tcp_allowed_congestion_control = cubic reno
net.ipv4.tcp_max_ssthresh = 0
net.ipv4.tcp_thin_linear_timeouts = 0
net.ipv4.tcp_thin_dupack = 0
W załączeniu jest kilka zdjęć grafów IO Wireshark niektórych przypadków testowych (przepraszam, nie mogę jeszcze publikować zdjęć bezpośrednio):
Przypadek testowy 1 (100 Mb / s -> 100 Mb / s) - niezły, płynny transfer. Brak strat w schwytaniu. - http://103.imagebam.com/download/dyNftIGh-1iCFbjfMFvBQw/25498/254976014/100m.png
Przypadek testowy 3 (1 Gb / s -> 100 Mb / s) - przesłanie głosu pocztą elektroniczną, osiągnięcie prędkości zajmuje dużo czasu - nigdy nie osiąga prędkości 100 Mb / s. Jeszcze żadnych strat / retransmisji podczas przechwytywania! - http://101.imagebam.com/download/KMYXHrLmN6l0Z4KbUYEZnA/25498/254976007/1g.png
Podsumowując, gdy używane jest długie łącze z połączeniem 1 Gb / s, uzyskujemy znacznie niższą przepustowość TCP niż w przypadku połączenia 100 Mb / s.
Byłbym bardzo wdzięczny za wskazówki od ekspertów TCP!
Dzięki!
AKTUALIZACJA (29.05.2013):
Rozwiązaliśmy problem z przypadkiem testowym nr 4 powyżej (nadawca 1 Gb / s, odbiornik 1 Gb / s, w dużym RTT). Możemy teraz osiągnąć ~ 970 Mb / s w ciągu kilku sekund od rozpoczęcia transferu. Wydaje się, że problem dotyczy przełącznika używanego przez dostawcę hostingu. Przejście do innego rozwiązało to.
Jednak przypadek testowy nr 3 w większości pozostaje problematyczny. Jeśli mamy odbiornik działający z prędkością 100 Mb / s, a nadawca z prędkością 1 Gb / s, to widzimy około 2-3 minut oczekiwania na osiągnięcie przez odbiornik 100 Mb / s (ale teraz osiąga pełną prędkość, inaczej niż wcześniej). Gdy tylko obniżymy nadawcę do 100 Mb / s lub zwiększymy odbiornik do 1 Gb / s, problem znika i możemy przyspieszyć do pełnej prędkości za sekundę lub dwie.
Głównym powodem jest to, że widzimy straty, oczywiście wkrótce po rozpoczęciu transferu. Nie oznacza to jednak, że rozumiem, jak działa powolny start; szybkość interfejsu nie powinna mieć na to żadnego wpływu, ponieważ powinna być regulowana przez potwierdzenia z odbiornika.
Proszę o sugestie z wdzięcznością! Gdybym mógł zaoferować nagrodę tutaj, zrobiłbym to!
tcp_*mem = 4096 1048576 33554432
Nie masz włączonych ramek Jumbo na łączach 1 Gb / s, prawda? To może gdzieś powodować fragmentację.