为什么在Xen下TCP接受()性能如此糟糕?

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

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

背景

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

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

当在裸机上testing相同的场景时,我得到的testing结果显示TCP接受速率超过35000 /秒。 在一台运行Ubuntu的Core i5 4核心机器上,所有内核几乎全部饱和。 对我来说,这种数字似乎是正确的。

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

我知道虚拟化运行时性能会下降。 但是到了这个程度? 速度较慢的裸机服务器性能优于虚拟化技术。 8核的系数是5?

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

重现这种行为

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

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

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

为什么这很重要?

在ESN (我的雇主),我是用Java编写的Comet / Web Socket服务器Beaconpush的项目负责人。 即使它性能非常好,在最佳条件下几乎可以使任何带宽达到饱和,但仍然限于新的TCP连接速度。 也就是说,如果用户stream失频繁,那么很多TCP连接将不得不build立起来。 我们尽量减less这种保持连接的活力。 但最后,accept()的性能是让我们的内核不能旋转,我们不喜欢这样做。


更新1

有人把这个问题发给了黑客新闻 ,那里也有一些问题/答案。 但是,我会尽量保持这个问题的最新信息,随着我的发现。

硬件/平台我已经testing了这个:

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

我正在重新运行这些testing,并填写报告在https://gist.github.com/985475如果你想帮助,贡献你的号码。 这很容易!

(行动计划已经转移到单独的综合答案)

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

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

    根据HN(KVM开发人员)上的用户,这是由于Xen和KVM中的小型数据包性能造成的。 这是一个已知的虚拟化问题,据他介绍,VMWare的ESX可以更好地处理这个问题。 他还指出,KVM正在devise一些新function来缓解这个( 原文 )。

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

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

    目前的行动计划基于这里和来自HN的答复/答案:

    1. 将此问题提交给Xen特定的邮件列表以及syneticon-djbuild议的xensource的bugzilla 邮件已发布到xen用户列表 ,等待回复。

    2. 创build一个简单的病态应用程序级testing用例并发布它。
      带有指令的testing服务器已经创build并发布到GitHub 。 与netperf相比,你应该能够看到更真实的用例。

    3. 尝试使用32位PV Xen来宾实例,因为64位可能会在Xen中造成更多的开销。 有人在HN上提到过这个。 没有什么区别。

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

    5. 将积压从1024增加到更高,也是由HN提出的。 这可能也有帮助,因为guest可能会在dom0(主机)给出的执行片段期间接受更多的连接。

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

    7. 检查“在netstat -s中侦听队列溢出和同步缓冲区溢出”(由HN上的mike_esspebuild议)。

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

    9. closuresTCP分段卸载并按照Matt Bailey的build议分散/收集加速。 (在EC2或类似VPS主机上不可能)

    有趣的是,我发现closures网卡硬件加速大大提高了Xen控制器上的networking性能(对于LXC也是如此):

    分散聚集accell:

    /usr/sbin/ethtool -K br0 sg off

    TCP分段卸载:

    /usr/sbin/ethtool -K br0 tso off

    br0是pipe理程序主机上的桥接器或networking设备。 您必须将其设置为在每次启动时closures。 因人而异。

    也许你可以澄清一点 – 你是否在自己的服务器上运行Xen下的testing,或者只在EC2实例上运行testing?

    Accept只是另一个系统调用,新的连接只不过是前几个数据包会有一些特定的标志 – 像Xen这样的pipe理程序绝对不会有任何区别。 你的设置的其他部分可能:例如在EC2中,如果安全组与它有关系,我不会感到惊讶; 据报道, conntrack 新的连接接受率(PDF)减less一半 。

    最后,似乎有CPU /内核的组合,导致EC2(也可能是一般的Xen)CPU奇怪的使用/挂断,如最近Librato博客 。

    确保你禁用dom0中桥接代码中的iptables和其他钩子。 显然它只适用于桥接networkingXen设置。

     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 

    这取决于服务器的大小,但在较小的(四核处理器)专用一个CPU核心到Xen dom0并钉住它。 pipe理程序启动选项:

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

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