Chúng tôi đã có cơ sở hạ tầng phân phối ở một vài địa điểm lớn trên thế giới - Singapore, London và Los Angeles. RTT giữa hai vị trí bất kỳ là hơn> 150ms.
Gần đây chúng tôi đã nâng cấp tất cả các máy chủ để sử dụng các liên kết 1Gbps (từ 100Mbps). Chúng tôi đã chạy một số thử nghiệm dựa trên TCP giữa các máy chủ tại các địa điểm khác nhau và đã thấy một số kết quả đáng ngạc nhiên. Những kết quả này là hoàn toàn lặp lại.
- Los Angeles (100Mbps) đến Luân Đôn (100Mbps): thông lượng ~ 96Mbps
- Los Angeles (100Mbps) đến Luân Đôn (1Gbps): thông lượng ~ 96Mbps
- Los Angeles (1Gbps) đến Luân Đôn (100Mbps): thông lượng 10-40Mbps (không ổn định)
- Los Angeles (1Gbps) đến Luân Đôn (1Gbps): thông lượng 10-40Mbps (không ổn định)
- Los Angeles (1Gbps) đến Los Angeles (1Gbps):> thông lượng 900Mbps
Dường như bất cứ khi nào người gửi chạy ở tốc độ 1Gbps, thông lượng của chúng tôi bị ảnh hưởng rất lớn qua các liên kết dài.
Cách tiếp cận thử nghiệm trước đó cực kỳ đơn giản - Tôi chỉ sử dụng cURL để tải xuống tệp nhị phân 1GB từ máy chủ đích (vì vậy trong trường hợp trên, máy khách cURL chạy trên máy chủ Luân Đôn và tải xuống từ LA, để LA là người gửi) . Tất nhiên, đây là sử dụng một kết nối TCP.
Lặp lại các thử nghiệm tương tự trên UDP bằng iperf, vấn đề sẽ biến mất!
- Los Angeles (100Mbps) đến Luân Đôn (100Mbps): thông lượng ~ 96Mbps
- Los Angeles (100Mbps) đến Luân Đôn (1Gbps): thông lượng ~ 96Mbps
- Los Angeles (1Gbps) đến Luân Đôn (100Mbps): thông lượng ~ 96Mbps
- Los Angeles (1Gbps) đến Luân Đôn (1Gbps):> thông lượng 250Mbps
Điều này chỉ thẳng vào một số vấn đề cấu hình TCP hoặc NIC / cổng trong mắt tôi.
Cả hai máy chủ đều đang chạy CentOS 6.x, với khối TCP. Cả hai đều có cửa sổ gửi và nhận TCP tối đa 8 MB và có dấu thời gian TCP và xác nhận chọn lọc được bật. Cấu hình TCP giống nhau được sử dụng trong tất cả các trường hợp thử nghiệm. Cấu hình TCP đầy đủ bên dưới:
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
Kèm theo là một vài hình ảnh đồ thị IO của wireshark của một số trường hợp thử nghiệm (xin lỗi, tôi chưa thể đăng hình ảnh trực tiếp):
Trường hợp thử nghiệm 1 (100Mbps -> 100Mbps) - chuyển tốt đẹp. Không có tổn thất trong việc nắm bắt. - http://103.imagebam.com/doad/dyNftIGh-1iCFbjfMFvBQw/25498/254976014/100m.png
Trường hợp thử nghiệm 3 (1Gbps -> 100Mbps) - chuyển giao biểu quyết, mất nhiều thời gian để đạt được bất kỳ tốc độ nào - không bao giờ đạt tới 100Mbps. Tuy nhiên, không có tổn thất / truyền lại trong việc nắm bắt! - http://101.imagebam.com/doad/KMYXHrLmN6l0Z4KbUYEZnA/25498/254976007/1g.png
Vì vậy, tóm lại, khi một liên kết dài được sử dụng với kết nối 1Gbps, chúng ta sẽ có thông lượng TCP thấp hơn nhiều so với khi chúng ta sử dụng kết nối 100Mbps.
Tôi rất đánh giá cao một số gợi ý từ bất kỳ chuyên gia TCP nào ngoài đó!
Cảm ơn!
CẬP NHẬT (2013-05-29):
Chúng tôi đã giải quyết vấn đề với trường hợp thử nghiệm số 4 ở trên (người gửi 1Gbps, người nhận 1Gbps, qua RTT lớn). Bây giờ chúng tôi có thể đạt ~ 970Mbps trong vòng vài giây kể từ khi bắt đầu chuyển. Vấn đề dường như là một chuyển đổi được sử dụng với nhà cung cấp dịch vụ lưu trữ. Chuyển đến một cái khác đã giải quyết điều đó.
Tuy nhiên, trường hợp thử nghiệm # 3 chủ yếu vẫn còn có vấn đề. Nếu chúng ta có một máy thu chạy ở tốc độ 100Mbps và người gửi ở tốc độ 1Gbps, thì chúng ta sẽ thấy khoảng 2-3 phút chờ đợi cho máy thu đạt 100Mbps (nhưng hiện tại nó đã đạt đến tốc độ đầy đủ, không giống như trước đây). Ngay sau khi chúng tôi thả người gửi xuống 100Mbps hoặc tăng người nhận lên 1Gbps, thì vấn đề sẽ biến mất và chúng tôi có thể tăng tốc độ tối đa trong một hoặc hai giây.
Lý do cơ bản là chúng tôi đang thấy thua lỗ, tất nhiên, rất nhanh sau khi chuyển khoản bắt đầu. Tuy nhiên, điều này không phù hợp với sự hiểu biết của tôi về cách khởi động chậm; tốc độ giao diện không nên có bất kỳ ảnh hưởng nào đến điều này, vì nó phải chịu sự chi phối của ACK từ máy thu.
Xin vui lòng nhận được lời đề nghị! Nếu tôi có thể cung cấp một tiền thưởng ở đây, tôi sẽ!
tcp_*mem = 4096 1048576 33554432
Bạn chưa kích hoạt Khung Jumbo trên các liên kết 1Gbps phải không? Điều đó có thể gây ra sự phân mảnh trên đầu ở đâu đó.