在大型RTT上,1Gbps服务器的TCP吞吐量比100Mbps服务器的TCP吞吐量低


9

我们的基础设施分布在全球几个主要地区-新加坡,伦敦和洛杉矶。任何两个位置之间的RTT均超过150ms。

我们最近将所有服务器升级为使用1Gbps链接(从100Mbps开始)。我们已经在不同位置的服务器之间运行了一些基于TCP的测试,并且看到了一些令人惊讶的结果。这些结果是完全可重复的。

  1. 洛杉矶(100Mbps)到伦敦(100Mbps):〜96Mbps吞吐量
  2. 洛杉矶(100Mbps)至伦敦(1Gbps):〜96Mbps吞吐量
  3. 洛杉矶(1Gbps)至伦敦(100Mbps):10-40Mbps吞吐量(易失)
  4. 洛杉矶(1Gbps)至伦敦(1Gbps):10-40Mbps吞吐量(易失)
  5. 洛杉矶(1Gbps)至洛杉矶(1Gbps):吞吐量> 900Mbps

看起来,只要发件人以1Gbps的速度运行,在长链路上,我们的吞吐量就会受到极大影响。

先前的测试方法非常简单-我只是使用cURL从目标服务器下载1GB二进制文件(因此,在上述情况下,cURL客户端在London服务器上运行并从LA下载,因此LA是发送者) 。当然,这是使用单个TCP连接。

使用iperf在UDP上重复相同的测试,问题消失了!

  1. 洛杉矶(100Mbps)到伦敦(100Mbps):〜96Mbps吞吐量
  2. 洛杉矶(100Mbps)至伦敦(1Gbps):〜96Mbps吞吐量
  3. 洛杉矶(1Gbps)至伦敦(100Mbps):〜96Mbps吞吐量
  4. 洛杉矶(1Gbps)至伦敦(1Gbps):吞吐量> 250Mbps

这直指我眼中的某些TCP或NIC /端口配置问题。

两台服务器都运行带有TCP三次的CentOS6.x。两者都具有最大8MB的TCP发送和接收窗口,并启用了TCP时间戳和选择性确认。所有测试用例都使用相同的TCP配置。完整的TCP配置如下:

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

附带的是一些测试用例的wireshark IO图的几个图像(对不起,我还不能直接发布图像):

测试案例1(100Mbps-> 100Mbps) -流畅的传输。没有损失。- http://103.imagebam.com/download/dyNftIGh-1iCFbjfMFvBQw/25498/254976014/100m.png

测试案例3( 1Gbps- > 100Mbps) -可变传输,需要很长时间才能达到任何速度-永远不会接近100Mbps。捕获中没有丢失/转发!- http://101.imagebam.com/download/KMYXHrLmN6l0Z4KbUYEZnA/25498/254976007/1g.png

因此,总而言之,当长链接与1Gbps连接一起使用时,与使用100Mbps连接时相比,我们获得的TCP吞吐量要低得多。

非常感谢任何TCP专家的指导!

谢谢!

更新(2013-05-29):

我们已经通过上面的测试案例4(在大型RTT上发送1Gbps,接收1Gbps的接收器)解决了该问题。现在,我们可以在传输开始后的几秒钟内达到970Mbps。该问题似乎是与托管服务提供商一起使用的一个开关。转向另一种解决了这一问题。

但是,第3个测试案例仍然存在问题。如果我们有一个接收器以100Mbps的速度运行而发送器以1Gbps的速度运行,那么我们将等待大约2-3分钟的时间来等待接收器达到100Mbps(但与以前不同,它现在已经达到了全速率)。一旦将发送器的速度降低到100Mbps或将接收器的速度提高到1Gbps,问题就消失了,我们可以在一两秒钟内将速度提升到全速。

根本原因是,在转移开始后不久,我们当然会看到损失。但是,这与我对慢启动的工作原理的理解并不一致。接口速度对此没有任何影响,因为它应该由接收器的ACK来控制。

建议感激地收到!如果我可以在这里提供赏金,我会的!


1
您是否正在两侧的NIC上使用TCP卸载?从100M到1G NIC,TCP卸载的用法是否有所不同?如果在任何测试用例中都使用了该功能,可能值得重复测试一下禁用该功能,只是为了查看100M NIC上的TCP卸载引擎是否可能妨碍1G通信的执行方式(此注释是有意为之的)。挥手只是为了一般地抬起脚趾)
FliesLikeABrick

好问题!两端的TCP分段卸载均处于禁用状态。两端均启用了通用分段卸载。我还在启用TSO的情况下重复了此操作,但并没有什么明显的不同。
山姆

尝试至少在100M端禁用通用分段卸载,然后重复测试
FliesLikeABrick

感谢您的建议,但没有喜悦-两侧打开或关闭gso的结果相同。
山姆

150ms +时1Gbps提供了非常大的带宽延迟乘积,超过18Mb。如果您增加套接字缓冲区会怎样?tcp_*mem = 4096 1048576 33554432您尚未在1Gbps链路上启用巨型帧吗?这可能会导致某个地方的碎片开销。
suprjami

Answers:


1

主要问题是WAN延迟大。如果它也丢失了随机数据包,那将是非常糟糕的。

1,tcp_mem还需要设置较大才能分配更多的内存。例如,将其设置为net.ipv4.tcp_mem = 4643328 6191104 9286656

2,您可以通过wireshark / tcpdump捕获数据包大约几分钟,然后分析是否有随机丢失的数据包。如果愿意,您还可以上传数据包文件。

3,您可以尝试调整其他tcp参数,例如。设置tcp_westwood = 1和tcp_bic = 1


谢谢,但是我们已经尝试了所有这些方法。WAN延迟不是问题-如果我们使用100Mbps端口,我们几乎可以立即达到100Mbps,但是只要将其更改为1Gbps,我们就可以敬酒。
山姆

1

解决了!有关完整的详细信息,请参见http://comments.gmane.org/gmane.linux.drivers.e1000.devel/11813

简而言之,看来连接1Gbps的服务器会在TCP的指数增长阶段发送大量流量,这将淹没某些中间设备(谁知道)中的缓冲区。剩下两个选择:

1)与每个中间网络运营商联系,并让他们配置适当的缓冲区以允许我所需的带宽和RTT。不太可能!2)限制连发。

我选择限制每个TCP流最多以100Mbps运行。这里的数字相当随意-我选择100Mbps纯粹是因为我知道以前的路径可以处理100Mbps,而且我不需要一个单独的流

希望这对以后的人有所帮助。


0

使用iperf在UDP上重复相同的测试,问题消失了!

洛杉矶(1Gbps)至伦敦(1Gbps):吞吐量> 250Mbps

问题似乎并没有消失,大约75%的数据包被丢弃了吗?如果TCP始终处于缓慢启动状态,则您的平均带宽可能会很低。

顺便说一句,您是否有伦敦到洛杉矶以及伦敦到伦敦的基准?


我忘了提到客户端是一个慢的客户端...如果我们重复两个快速的客户端,那么我们双向达到〜970Mbps。
山姆
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.