Singapur, Londra ve Los Angeles olmak üzere dünyanın çeşitli yerlerinde altyapıya sahibiz. Herhangi iki konum arasındaki RTT> 150 ms'nin üzerindedir.
Kısa bir süre önce tüm sunucuları 1 Gbps bağlantı kullanacak şekilde yükselttik (100 Mbps'den). Farklı konumlardaki sunucular arasında bazı TCP tabanlı testler yürütüyoruz ve bazı şaşırtıcı sonuçlar elde ettik. Bu sonuçlar tamamen tekrarlanabilir.
- Los Angeles (100Mbps) - Londra (100Mbps): ~ 96Mbps üretim hacmi
- Los Angeles (100Mbps) - Londra (1Gbps): ~ 96Mbps üretim hacmi
- Los Angeles (1Gbps) - Londra (100Mbps): 10-40Mbps işlem hacmi (uçucu)
- Los Angeles (1Gbps) - Londra (1Gbps): 10-40Mbps işlem hacmi (uçucu)
- Los Angeles (1Gbps) - Los Angeles (1Gbps):> 900Mbps işlem hacmi
Gönderen her 1 Gbps'de çalıştığında, iş hacmimizin uzun bağlantılar üzerinde çok önemli ölçüde acı çektiği görülmektedir.
Daha önce test yaklaşımı son derece basit - sadece hedef sunucudan 1 GB'lık bir ikili dosya indirmek için cURL kullanıyorum (bu nedenle yukarıdaki durumda, cURL istemcisi Londra sunucusunda çalışır ve LA'dan indirir, böylece LA gönderen olur) . Bu elbette tek bir TCP bağlantısı kullanıyor.
Aynı testleri iperf kullanarak UDP üzerinden tekrarlayarak sorun ortadan kalkar!
- Los Angeles (100Mbps) - Londra (100Mbps): ~ 96Mbps üretim hacmi
- Los Angeles (100Mbps) - Londra (1Gbps): ~ 96Mbps üretim hacmi
- Los Angeles (1Gbps) - Londra (100Mbps): ~ 96Mbps işlem hacmi
- Los Angeles (1Gbps) - Londra (1Gbps):> 250Mbps işlem hacmi
Bu, gözlerimdeki bazı TCP veya NIC / bağlantı noktası yapılandırma sorununa dikkat çekiyor.
Her iki sunucu da TCP kübik ile CentOS 6.x çalıştırıyor. Her ikisinde de maksimum 8MB TCP gönderme ve alma penceresi ve TCP zaman damgaları ile seçici alındı bildirimleri etkin. Tüm test durumlarında aynı TCP yapılandırması kullanılır. Tam TCP yapılandırması aşağıdadır:
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
Bazı test senaryolarının wireshark IO grafiklerinin birkaç resmi eklenmiştir (üzgünüm, henüz görüntüleri doğrudan gönderemiyorum):
Test durumu 1 (100Mbps -> 100Mbps) - güzel sorunsuz aktarım. Yakalamada kayıp yok. - http://103.imagebam.com/download/dyNftIGh-1iCFbjfMFvBQw/25498/254976014/100m.png
Test durumu 3 (1Gbps -> 100Mbps) - geçici aktarım, herhangi bir hıza ulaşmak uzun zaman alır - asla 100Mbps'ye yaklaşmaz. Ancak yakalamada kayıp / yeniden iletim yok! - http://101.imagebam.com/download/KMYXHrLmN6l0Z4KbUYEZnA/25498/254976007/1g.png
Özet olarak, 1Gbps bağlantıda uzun bir bağlantı kullanıldığında, 100Mbps bağlantı kullandığımızdan çok daha düşük bir TCP verimi elde ederiz.
Orada herhangi bir TCP uzmanından bazı işaretçiler çok takdir ediyorum!
Teşekkürler!
GÜNCELLEME (2013-05-29):
Yukarıdaki test durumu # 4 ile sorunu çözdük (büyük bir RTT üzerinden 1Gbps gönderici, 1Gbps alıcı). Artık aktarımın başlamasından birkaç saniye sonra ~ 970Mbps'ye ulaşabiliriz. Sorun , barındırma sağlayıcısı ile kullanılan bir anahtar gibi görünüyor . Farklı birine geçmek bunu çözdü.
Bununla birlikte, test durumu # 3 çoğunlukla sorunlu olmaya devam etmektedir. 100Mbps hızında çalışan bir göndericimiz ve 1Gbps hızında gönderenimiz varsa, alıcının 100Mbps'ye ulaşması için yaklaşık 2-3 dakikalık bir bekleme görürüz (ancak daha önce aksine tam hıza ulaşır). Göndereni 100Mbps'ye düşürdüğümüzde veya alıcıyı 1Gbps'ye çıkardığımızda sorun ortadan kalkar ve bir veya iki saniye içinde tam hıza yükselebiliriz.
Bunun altında yatan neden, elbette, transfer başladıktan hemen sonra kayıplar görmemizdir. Ancak bu, yavaş başlatmanın nasıl çalıştığına dair anlayışımla uyuşmuyor; arayüz hızının alıcı üzerinde ACK'lar tarafından yönetilmesi gerektiği için bunun üzerinde herhangi bir etkisi olmamalıdır.
Öneriler minnetle alındı lütfen! Burada bir lütuf teklif edebilirsem, yapardım!
tcp_*mem = 4096 1048576 33554432
1Gbps bağlantılarında Jumbo Çerçeveleri etkinleştirmediniz mi? Bu, bir yerde havai parçalanmaya neden olabilir.