背景

背景

在 Xen 下,我的服务器 accept() 新传入 TCP 连接的速度非常差。在裸机硬件上进行的相同测试显示速度提高了 3-5 倍。

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

背景

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

但即使向服务器发送大量流量,它也无法接受每秒超过约 7000 个 TCP 连接(在运行 Xen 的 8 核 EC2 实例 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 的 TCP_CRR 测试,我收集了来自不同服务器(虚拟化和非虚拟化)的各种报告。如果您想提供一些发现或查看我当前的报告,请参阅https://gist.github.com/985475

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

  1. 该服务器已在裸机硬件上进行了测试,并且几乎饱和了所有可用的核心。
  2. 当使用保持活动的 TCP 连接时,问题就消失。

为什么这很重要?

电子序列号(我的雇主)我是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 实例无法推送超过 100k PPS。
  • 两台运行 Xen 的私有虚拟化服务器。其中一台在测试前负载为零,但没有什么变化。
  • Rackspace 的专用 Xen 服务器。结果大致相同。

我正在重新进行这些测试并填写报告https://gist.github.com/985475如果你想帮忙,贡献你的号码吧。很简单!

(该行动计划已移至单独合并的答复)

答案1

目前:Xen 下的小数据包性能很差

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

据 HN 上的一位用户(KVM 开发人员?)称,这是由于 Xen 和 KVM 中的小数据包性能所致。这是虚拟化的一个已知问题,据他所说,VMWare 的 ESX 处理这个问题要好得多。他还指出,KVM 正在引入一些旨在缓解这个问题的新功能(原始帖子)。

如果这些信息正确的话,那有点令人沮丧。无论如何,我会尝试以下步骤,直到一些 Xen 专家给出明确的答案 :)

xen-users 邮件列表的 Iain Kay 编制了此图表: netperf 图 注意 TCP_CRR 条,比较“2.6.18-239.9.1.el5”与“2.6.39 (带有 Xen 4.1.0)”。

当前行动计划基于此处和以下来源的回复/答案

  1. 按照 syneticon-dj A的建议,将此问题提交给 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. 将积压量从 1024 增加到更高的值,这也是 abofh 在 HN 上提出的建议。这也可能有帮助,因为客户机在由 dom0(主机)提供的执行片段中可能会 accept() 更多连接。

  6. 仔细检查所有机器上的 conntrack 是否已禁用,因为它会使接受率减半(由 deubeulyou 建议)。是的,它在所有测试中均已禁用。

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

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

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

答案2

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

分散-聚集加速度:

/usr/sbin/ethtool -K br0 sg off

TCP 分段卸载:

/usr/sbin/ethtool -K br0 tso off

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

答案3

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

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

最后,似乎存在一些 CPU/内核组合,会导致 EC2(可能还有 Xen)出现奇怪的 CPU 使用率/挂断现象,例如Librato 最近在博客中提到

答案4

确保在 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 并固定它。虚拟机管理程序启动选项:

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

您是否尝试过将物理以太网 PCI 设备传递到 domU?性能应该会大幅提升。

相关内容