为什么在 Xen 下 TCP accept() 性能这么差?

cgb*_*rom 89 virtualization linux performance xen amazon-ec2

我的服务器可以接受()新传入 TCP 连接的速率在 Xen 下非常糟糕。对裸机硬件的相同测试显示速度提高了 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. 使用保持活动的 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。有人还指出,“安全组”(即 EC2 防火墙)也可能会受到影响。但是对于这个测试场景,我只尝试在本地主机上消除诸如此类的外部因素。我听到的另一个传闻是 EC2 实例的 PPS 不能超过 100k。
  • 两个运行 Xen 的私有虚拟化服务器。一个在测试前的负载为零,但没有任何区别。
  • Rackspace 的专用 Xen 服务器。那里的结果大致相同。

我正在重新运行这些测试并填写https://gist.github.com/985475 上的报告。如果您愿意提供帮助,请贡献您的数字。这很简单!

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

cgb*_*rom 27

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

(改为从问题本身移至单独的答案)

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

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

来自 xen-users 邮件列表的 Iain Kay 编译了这张图: 网络性能图 注意 TCP_CRR 条,比较“2.6.18-239.9.1.el5”与“2.6.39(使用 Xen 4.1.0)”。

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

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

  2. 创建一个简单的病理性、应用级测试用例并发布。
    带有说明的测试服务器已创建并发布到 GitHub。有了这个,与 netperf 相比,您应该能够看到更真实的用例。

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

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

  5. 将 backlog 从 1024 增加到更高,这也是 abofh 在 HN 上的建议。这也可能有所帮助,因为在由 dom0(主机)给出的执行切片期间,来宾可能会接受更多的连接。

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

  7. 检查“netstat -s 中的侦听队列溢出和同步缓存桶溢出”(由 HN 上的 mike_esspe 建议)。

  8. 在多个内核之间拆分中断处理(我之前尝试启用的 RPS/RFS 应该可以做到这一点,但可能值得再试一次)。由 HN 的 Adamt 建议。

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

  • +1 当您发现时,一定要发布性能结果! (2认同)

小智 21

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

分散聚集加速器:

/usr/sbin/ethtool -K br0 sg off

TCP 分段卸载:

/usr/sbin/ethtool -K br0 tso off

其中 br0 是虚拟机管理程序主机上的网桥或网络设备。您必须设置它以在每次启动时将其关闭。天啊。