Kami memiliki infrastruktur yang didistribusikan di beberapa lokasi utama di seluruh dunia - Singapura, London dan Los Angeles. RTT antara dua lokasi lebih dari> 150 ms.
Kami baru saja memutakhirkan semua server untuk menggunakan tautan 1Gbps (dari 100Mbps). Kami telah menjalankan beberapa pengujian berbasis TCP antara server di lokasi yang berbeda dan telah melihat beberapa hasil yang mengejutkan. Hasil ini sepenuhnya dapat diulang.
- Los Angeles (100Mbps) ke London (100Mbps): ~ 96Mbps throughput
- Los Angeles (100Mbps) ke London (1Gbps): ~ 96Mbps throughput
- Los Angeles (1Gbps) ke London (100Mbps): 10-40Mbps throughput (volatile)
- Los Angeles (1Gbps) ke London (1Gbps): 10-40Mbps throughput (volatile)
- Los Angeles (1Gbps) ke Los Angeles (1Gbps):> 900Mbps throughput
Tampaknya setiap kali pengirim beroperasi pada 1Gbps, throughput kami sangat signifikan selama tautan yang panjang.
Pendekatan pengujian sebelumnya sangat sederhana - Saya hanya menggunakan cURL untuk mengunduh biner 1GB dari server target (jadi dalam kasus di atas, klien cURL berjalan di server London dan unduhan dari LA, sehingga LA adalah pengirim) . Ini menggunakan koneksi TCP tunggal tentunya.
Mengulangi tes yang sama pada UDP menggunakan iperf, masalahnya hilang!
- Los Angeles (100Mbps) ke London (100Mbps): ~ 96Mbps throughput
- Los Angeles (100Mbps) ke London (1Gbps): ~ 96Mbps throughput
- Los Angeles (1Gbps) ke London (100Mbps): ~ 96Mbps throughput
- Los Angeles (1Gbps) ke London (1Gbps):> throughput 250Mbps
Ini menunjuk tepat pada beberapa masalah konfigurasi TCP atau NIC / port di mata saya.
Kedua server menjalankan CentOS 6.x, dengan TCP cubic. Keduanya memiliki jendela kirim & terima TCP maksimum 8MB, dan cap waktu TCP dan ucapan terima kasih selektif diaktifkan. Konfigurasi TCP yang sama digunakan dalam semua kasus uji. Konfigurasi TCP lengkap ada di bawah:
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
Terlampir adalah beberapa gambar grafik IO wireshark dari beberapa kasus uji (maaf, saya belum dapat mengirim gambar langsung):
Test case 1 (100Mbps -> 100Mbps) - transfer halus yang bagus. Tidak ada kerugian dalam penangkapan. - http://103.imagebam.com/download/dyNftIGh-1iCFbjfMFvBQw/25498/254976014/100m.png
Test case 3 (1Gbps -> 100Mbps) - transfer votaile, membutuhkan waktu lama untuk mencapai kecepatan apa pun - tidak pernah mendekati 100Mbps. Namun tidak ada kerugian / transmisi ulang dalam penangkapan! - http://101.imagebam.com/download/KMYXHrLmN6l0Z4KbUYEZnA/25498/254976007/1g.png
Jadi secara ringkas, ketika tautan panjang digunakan dengan koneksi 1Gbps, kami mendapatkan throughput TCP yang jauh lebih rendah daripada ketika kami menggunakan koneksi 100Mbps.
Saya sangat menghargai beberapa petunjuk dari pakar TCP di luar sana!
Terima kasih!
UPDATE (2013-05-29):
Kami telah memecahkan masalah dengan test case # 4 di atas (pengirim 1Gbps, penerima 1Gbps, pada RTT besar). Kami sekarang dapat menekan ~ 970Mbps dalam beberapa detik sejak dimulainya transfer. Masalahnya tampaknya adalah saklar yang digunakan dengan penyedia hosting. Pindah ke yang berbeda memecahkannya.
Namun, uji kasus # 3 sebagian besar tetap bermasalah. Jika kita memiliki penerima yang berjalan pada 100Mbps dan pengirim di 1Gbps, maka kita melihat sekitar 2-3 menit menunggu penerima mencapai 100Mbps (tetapi sekarang mencapai tingkat penuh, tidak seperti sebelumnya). Segera setelah kami menurunkan pengirim ke 100Mbps atau menambah penerima ke 1Gbps, maka masalahnya hilang dan kami dapat meningkatkan kecepatan penuh dalam satu atau dua detik.
Alasan yang mendasarinya adalah bahwa kita melihat kerugian, tentu saja, segera setelah transfer dimulai. Namun, ini tidak sesuai dengan pemahaman saya tentang bagaimana start lambat bekerja; kecepatan antarmuka seharusnya tidak ada kaitannya dengan ini, karena harus diatur oleh ACK dari penerima.
Saran, terima kasih, terima kasih! Jika saya dapat menawarkan hadiah di sini, saya akan melakukannya!
tcp_*mem = 4096 1048576 33554432
Anda belum mengaktifkan Jumbo Frames pada tautan 1Gbps, bukan? Itu bisa menyebabkan fragmentasi di suatu tempat.