在 Xen 下,我的服务器 accept() 新传入 TCP 连接的速度非常差。在裸机硬件上进行的相同测试显示速度提高了 3-5 倍。
- 在 Xen 下这怎么会这么糟糕呢?
- 您能否调整 Xen 来提高新 TCP 连接的性能?
- 是否有其他虚拟化平台更适合这种用例?
背景
最近,我一直在研究内部开发的运行在 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 倍?
- 这真的是 Xen 预期的行为吗?
- 您能否调整 Xen 来提高新 TCP 连接的性能?
- 是否有其他虚拟化平台更适合这种用例?
重现此行为
当我进一步调查并确定问题时,我发现网络性能测试性能测试工具可以模拟我遇到的类似情况。使用 netperf 的 TCP_CRR 测试,我收集了来自不同服务器(虚拟化和非虚拟化)的各种报告。如果您想提供一些发现或查看我当前的报告,请参阅https://gist.github.com/985475
我怎么知道这个问题不是由于软件编写不佳造成的?
- 该服务器已在裸机硬件上进行了测试,并且几乎饱和了所有可用的核心。
- 当使用保持活动的 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 编制了此图表: 注意 TCP_CRR 条,比较“2.6.18-239.9.1.el5”与“2.6.39 (带有 Xen 4.1.0)”。
当前行动计划基于此处和以下来源的回复/答案氢:
按照 syneticon-dj A的建议,将此问题提交给 Xen 特定的邮件列表和 xensource 的 bugzilla消息已发布到 xen-user 列表,等待回复。创建一个简单的病理性应用程序级测试用例并发布。
已创建带有说明的测试服务器,发布到 GitHub. 通过这个,你应该能够看到与 netperf 相比更真实的用例。尝试 32 位 PV Xen 客户实例,因为 64 位可能会导致 Xen 产生更多开销。有人在 HN 上提到了这一点。没什么区别。尝试按照 HN 上的 abofh 的建议在 sysctl.conf 中启用 net.ipv4.tcp_syncookies。这显然可能提高性能,因为握手将发生在内核中。我在这方面没有运气。将积压量从 1024 增加到更高的值,这也是 abofh 在 HN 上提出的建议。这也可能有帮助,因为客户机在由 dom0(主机)提供的执行片段中可能会 accept() 更多连接。
仔细检查所有机器上的 conntrack 是否已禁用,因为它会使接受率减半(由 deubeulyou 建议)。是的,它在所有测试中均已禁用。检查“netstat -s 中的监听队列溢出和同步缓存桶溢出”(由 HN 上的 mike_esspe 建议)。
将中断处理拆分到多个核心之间(我之前尝试启用的 RPS/RFS 应该可以做到这一点,但可能值得再试一次)。由 HN 的 adamt 建议。
按照 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?性能应该会大幅提升。