题 在Xen下,为什么TCP accept()性能如此糟糕?


在Xen下,我的服务器可以接受()新的传入TCP连接的速度非常糟糕。裸机硬件上的相同测试显示3-5倍的加速。

  1. 如何在Xen下这么糟糕?
  2. 您是否可以调整Xen以提高新TCP连接的性能?
  3. 还有其他虚拟化平台更适合这种用例吗?

背景

最近我一直在研究在Xen下运行的内部开发的Java服务器的一些性能瓶颈。服务器说HTTP并回答简单的TCP连接/请求/响应/断开呼叫。

但即使在向服务器发送大量流量时,它也不能接受每秒超过7000个TCP连接(在8核EC2实例上运行Xen的c1.xlarge)。在测试期间,服务器还表现出一种奇怪的行为,其中一个核心(不一定是cpu 0)的负载非常大> 80%,而其他核心几乎保持空闲状态。这让我认为问题与内核/底层虚拟化有关。

在裸机,非虚拟化平台上测试相同的场景时,我得到的测试结果显示TCP accept()速率超过35 000 /秒。这是在运行Ubuntu的Core i5 4核心机器上,所有内核几乎完全饱和。对我来说,那种形象似乎是正确的。

再次在Xen实例上,我尝试启用/调整sysctl.conf中的几乎所有设置。包括启用 接收数据包转向 和 接收流量转向 并将线程/进程固定到CPU,但没有明显的收益。

我知道在运行虚拟化时可以预期降级性能。但到了这个程度?一种速度较慢的裸机服务器,性能优于virt。 8核5倍?

  1. 这是Xen真正预期的行为吗?
  2. 您是否可以调整Xen以提高新TCP连接的性能?
  3. 还有其他虚拟化平台更适合这种用例吗?

重现此行为

当进一步调查这个并查明问题时,我发现了 的netperf 性能测试工具可以模拟我遇到的类似场景。 使用netperf的TCP_CRR测试我收集了来自不同服务器(虚拟化和非虚拟化)的各种报告。如果您想提供一些调查结果或查看我当前的报告,请参阅 https://gist.github.com/985475

我怎么知道这个问题不是由于编写得不好的软件造成的?

  1. 该服务器已在裸机硬件上进行了测试,几乎可以使所有可用的内核饱和。
  2. 使用keep-alive TCP连接时,问题就消失了。

为什么这很重要?

ESN (我的雇主)我是项目负责人 Beaconpush,一个用Java编写的Comet / Web Socket服务器。即使它具有非常高的性能并且几乎可以在最佳条件下为其提供任何带宽,但它仍然受限于新TCP连接的速度。也就是说,如果您经常有大量用户流失,用户经常来去,那么就必须设置/拆除许多TCP连接。我们尽可能地减轻这种保持连接的速度。 但最终,accept()性能使我们的核心不再旋转,我们不喜欢这样。


更新1

有人 将此问题发布到Hacker News,那里也有一些问题/答案。但我会尝试将这个问题与我发现的最新信息保持同步。

硬件/平台我测试过这个:

  • EC2,实例类型为c1.xlarge(8核,7 GB RAM)和cc1.4xlarge(2x Intel Xeon X5570,23 GB RAM)。使用的AMI分别是ami-08f40561和ami-1cad5275。有人还指出,“安全组”(即EC2s防火墙)也可能会受到影响。但是对于这个测试场景,我只尝试使用localhost来消除这种外部因素。我听到的另一个谣言是EC2实例不能超过10万PPS。
  • 运行Xen的两台私有虚拟服务器。一个人在测试之前没有负载,但没有产生任何影响。
  • Rackspace专用的Xen服务器。那里的结果差不多。

我正在重新运行这些测试并填写报告 https://gist.github.com/985475 如果您想提供帮助,请提供您的号码。这很简单!

(行动计划已移至单独的综合答案)


87
2018-05-22 16:39




出色的工作指出了一个问题,但我相信你会在Xen特定的邮件列表,支持论坛甚至是 xensource错误报告网站。我相信这可能是一些调度程序错误 - 如果您使用7,000个连接数* 4个核心/ 0.80 CPU负载,您将获得35,000个 - 当4个核心完全饱和时您获得的数字。 - the-wabbit
啊,还有一件事:如果可以的话,为你的客人尝试不同的(可能是更新的)内核版本。 - the-wabbit
@ syneticon-dj谢谢。我确实在EC2的cc1.4xlarge上使用内核2.6.38进行了尝试。如果我没弄错的话,我看到了大约10%的增长。但更可能的原因是该实例类型的硬件更加强大。 - cgbystrom
感谢您与HN的回复保持同步,这是一个很好的问题。我建议将行动计划转移到综合答案中,因为这些都是问题的可能答案。 - Jeff Atwood
@jeff移动行动计划,检查。 - cgbystrom


答案:


现在:Xen下的小数据包性能很糟糕

(从问题本身转移到单独的答案)

根据HN(KVM开发人员?)上的用户的说法,这是由于Xen和KVM中的小数据包性能。这是虚拟化的一个已知问题,据他说,VMWare的ESX处理得更好。他还指出,KVM正在带来一些旨在缓解这一功能的新功能(原帖)。

如果这是正确的,这个信息有点令人沮丧。无论哪种方式,我将尝试以下步骤,直到一些Xen大师带来明确的答案:)

来自xen-users邮件列表的Iain Kay编译了这个图: netperf graph 注意TCP_CRR条,比较“2.6.18-239.9.1.el5”与“2.6.39(与Xen 4.1.0)”。

当前行动计划基于此处和之后的回答/答案 HN

  1. 按照syneticon-dj的建议,将此问题提交给Xen特定的邮件列表和xensource的bugzilla 一个 消息已发布到xen-user列表等待回复。

  2. 创建一个简单的病态,应用程序级测试用例并发布它。
    已创建带有指令的测试服务器 发表于GitHub。有了这个,你应该能够看到比netperf更真实的用例。

  3. 尝试使用32位PV Xen客户端实例,因为64位可能会导致Xen中的更多开销。有人在HN上提到了这一点。 没有什么区别。

  4. 尝试按照abofh在HN上的建议在sysctl.conf中启用net.ipv4.tcp_syncookies。这显然 威力 因为握手会在内核中发生,所以可以提高性能。 我没有运气。

  5. 将积压从1024增加到更高的水平,这也是abofh对HN的建议。这也可能有所帮助,因为guest虚拟机可能会在dom0(主机)给出的执行切片期间接受()更多连接。

  6. 仔细检查所有机器上是否禁用了conntrack,因为它可以将接受率减半(由deubeulyou建议)。 是的,它在所有测试中都被禁用。

  7. 检查“监听队列溢出和netstat -s中的syncache桶溢出”(由HIK上的mike_esspe建议)。

  8. 拆分多个内核之间的中断处理(我尝试先前启用的RPS / RFS应该这样做,但可能值得再次尝试)。由亚当在HN推荐。

  9. 按照Matt Bailey的建议关闭TCP分段卸载和分散/聚集加速。 (在EC2或类似的VPS主机上不可用)


26
2018-05-22 23:41



+1当您发现时,绝对发布效果结果! - chrisaycock
关于这个问题,有人在推特上戳了我一下。不幸的是,似乎这个问题仍然存在。自去年以来,我没有进行太多的研究。 Xen可能在此期间有所改进,我不知道。 KVM开发人员还提到他们正在解决这样的问题。值得追求。此外,我听到的另一个建议是尝试使用OpenVZ而不是Xen / KVM,因为它增加了很少或没有分层/拦截系统调用。 - cgbystrom


有趣的是,我发现关闭NIC硬件加速可以大大提高Xen控制器的网络性能(对于LXC也是如此):

分散聚集:

/usr/sbin/ethtool -K br0 sg off

TCP分段卸载:

/usr/sbin/ethtool -K br0 tso off

其中br0是管理程序主机上的桥接器或网络设备。您必须将其设置为在每次启动时将其关闭。因人而异。


20
2018-05-22 19:09



我是第二个。我在Xen上运行的Windows 2003服务器在高吞吐量条件下遇到了一些可怕的数据包丢失问题。当我禁用TCP段卸载时,问题就消失了 - rupello
谢谢。我根据您的建议更新了原始问题中的“行动计划”。 - cgbystrom
也可以看看 cloudnull.io/2012/07/xenserver-network-tuning - Lari Hotari


也许您可以澄清一下 - 您是在自己的服务器上运行Xen下的测试,还是仅在EC2实例上运行?

Accept只是另一个系统调用,新连接的不同之处在于前几个数据包将有一些特定的标志 - 像Xen这样的虚拟机管理程序肯定看不出任何区别。您的设置的其他部分可能是:例如,在EC2中,如果安全组与它有关,我不会感到惊讶; conntrack也是 据报道将新连接接受率减半(PDF)

最后,似乎有CPU /内核组合导致EC2(通常可能是Xen)上的CPU使用/挂断奇怪,如 最近由Librato发表了博客


2
2018-05-22 19:56



我更新了问题并澄清了我尝试过的硬件。 abofh还建议将积压增加到1024以上,以便在访客的执行切片期间加快可能的accept()的数量。关于conntrack,我绝对应该仔细检查这些事情是否被禁用,谢谢。我已经阅读了Liberato的文章,但考虑到我尝试使用不同硬件的数量,情况应该不是这样。 - cgbystrom


确保在dom0中的桥接代码中禁用了iptables和其他挂钩。显然它只适用于桥接网络Xen设置。

echo 0 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 0 > /proc/sys/net/bridge.bridge-nf-call-arptables

它取决于服务器的大小,但在较小的(4核处理器)上,将一个CPU核心专用于Xen dom0并固定它。 Hypervisor启动选项:

dom0_max_vcpus=1 dom0_vcpus_pin dom0_mem=<at least 512M>

您是否尝试将物理以太网PCI设备传递给domU?应该有很好的性能提升。


0
2018-02-11 11:35