我们的基础设施遍布世界各地 – 新加坡,伦敦和洛杉矶。 任何两个地点之间的RTT超过150毫秒。
我们最近升级了所有的服务器以使用1Gbps链路(从100Mbps)。 我们已经在不同地点的服务器之间运行了一些基于TCP的testing,并且看到了一些令人惊讶的结果。 这些结果是完全可重复的。
似乎每当发送者以1Gbps运行时,我们的吞吐量在长链接上受到非常大的影响。
之前的testing方法非常简单 – 我只是使用cURL从目标服务器下载1GB二进制文件(因此,在上述情况下,cURL客户端在伦敦服务器上运行并从洛杉矶下载,因此LA是发件人) 。 这当然是使用单个TCP连接。
使用iperf通过UDP重复相同的testing,问题消失!
这正好指出了一些TCP或NIC /端口configuration问题。
两台服务器都运行CentOS 6.x,使用TCP立方体。 最多有8MB的TCP发送和接收窗口,并且启用了TCP时间戳和select性确认。 所有testing用例都使用相同的TCPconfiguration。 完整的TCPconfiguration如下:
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
附上一些testing用例wireshark IOgraphics的图像(抱歉,我现在还不能直接发布图像):
testing案例1(100Mbps – > 100Mbps) – stream畅的传输。 捕获没有损失。 – http://103.imagebam.com/download/dyNftIGh-1iCFbjfMFvBQw/25498/254976014/100m.png
testing案例3(1Gbps – > 100Mbps) – votaile传输,需要很长时间才能达到任何速度 – 从不接近100Mbps。 然而,在捕获没有损失/转发! – http://101.imagebam.com/download/KMYXHrLmN6l0Z4KbUYEZnA/25498/254976007/1g.png
因此,总而言之,当长链接与1Gbps连接一起使用时,与使用100Mbps连接相比,TCP吞吐量要低得多。
我非常感谢来自任何TCP专家的指点!
谢谢!
更新(2013-05-29):
我们已经通过上面的testing案例4(1Gbps发送器,1Gbps接收器,在一个大的RTT上)解决了这个问题。 现在我们可以在传输开始的几秒钟内达到〜970Mbps。 这个问题似乎是主机提供商使用的一个交换机。 搬到另一个解决了。
但是,testing用例#3大多仍然存在问题。 如果我们有一个100Mbps的接收器和1Gbps的发送器,那么我们看到大约2-3分钟的等待接收器达到100Mbps(但现在达到了全速率,不像以前那样)。 一旦我们把发送器降到100Mbps或者把接收器增加到1Gbps,那么问题就消失了,我们可以在一秒钟或两秒钟内完全加速。
其根本原因是我们在转会开始后很快就会看到亏损。 但是,这与我对慢启动工作的理解不符, 接口速度不应该有任何影响,因为它应该由来自接收器的ACK来控制。
感谢您的build议! 如果我能在这里提供赏金,我会的!
主要问题是广域网延迟。 如果它也有随机丢包,那将会非常糟糕。
1,tcp_mem也需要设置大才能分配更多的内存。 例如,将其设置为net.ipv4.tcp_mem = 4643328 6191104 9286656
2,可以通过wireshark / tcpdump抓包几分钟左右,然后分析是否丢包。 你也可以上传数据包文件,如果你喜欢。
3,你可以尝试调整其他的TCP参数例如。 设置tcp_westwood = 1和tcp_bic = 1
解决了! 有关详细信息,请参阅http://comments.gmane.org/gmane.linux.drivers.e1000.devel/11813
简而言之,似乎1Gbps连接的服务器会在TCP的指数增长阶段发送突发stream量,这会在某些中间设备(谁知道是什么)中淹没缓冲区。 这留下了两个select:
1)联系每个中间networking运营商,让他们configuration适当的缓冲区,以允许我想要的带宽和RTT。 相当不可能! 2)限制突发。
我select限制每个TCPstream量最多以100Mbps运行。 这里的数字是相当随意的 – 我select100Mbps纯粹是因为我知道以前的path可以处理100Mbps,我不需要更多的个人stream量 。
希望这有助于未来的人。
使用iperf通过UDP重复相同的testing,问题消失!
洛杉矶(1Gbps)到伦敦(1Gbps):吞吐量> 250Mbps
问题似乎没有消失,你的数据包中的75%正在下降? 如果TCP始终处于缓慢启动状态,那么平均带宽可能会相当低。
顺便说一下,你有伦敦到洛杉矶和伦敦到伦敦的基准吗?