Warum ist die Leistung von TCP accept () unter Xen so schlecht?


89

Die Rate, mit der mein Server neue eingehende TCP-Verbindungen akzeptieren kann, ist unter Xen wirklich schlecht. Der gleiche Test auf Bare-Metal-Hardware zeigt 3-5-fache Geschwindigkeitssteigerungen.

  1. Wieso ist das unter Xen so schlimm?
  2. Können Sie Xen optimieren, um die Leistung für neue TCP-Verbindungen zu verbessern?
  3. Gibt es andere Virtualisierungsplattformen, die für diese Art von Anwendungsfällen besser geeignet sind?

Hintergrund

In letzter Zeit habe ich einige Leistungsengpässe eines eigens entwickelten Java-Servers unter Xen untersucht. Der Server spricht HTTP und beantwortet einfache TCP-Verbindungs- / Anforderungs- / Antwort- / Trennungsanrufe.

Aber selbst wenn eine Schiffsladung Verkehr an den Server gesendet wird, können nicht mehr als ~ 7000 TCP-Verbindungen pro Sekunde akzeptiert werden (auf einer 8-Core-EC2-Instanz, c1.xlarge mit Xen). Während des Tests zeigt der Server auch ein merkwürdiges Verhalten, bei dem ein Kern (nicht unbedingt CPU 0) zu mehr als 80% ausgelastet ist, während die anderen Kerne fast untätig bleiben. Dies lässt mich glauben, dass das Problem mit dem Kernel / der zugrunde liegenden Virtualisierung zusammenhängt.

Wenn ich dasselbe Szenario auf einer nicht virtualisierten Bare-Metal-Plattform teste, erhalte ich Testergebnisse, die TCP-Accept () - Raten über 35.000 / Sekunde anzeigen. Dies auf einer Core i5 4 Core-Maschine, auf der Ubuntu ausgeführt wird, wobei alle Kerne fast voll ausgelastet sind. Für mich scheint diese Art von Figur ungefähr richtig zu sein.

Auf der Xen-Instanz habe ich erneut versucht, fast alle Einstellungen in sysctl.conf zu aktivieren / optimieren. Einschließlich der Aktivierung von Receive Packet Steering und Receive Flow Steering sowie des Fixierens von Threads / Prozessen auf CPUs, jedoch ohne erkennbare Vorteile.

Ich weiß, dass eine verminderte Leistung zu erwarten ist, wenn virtualisiert ausgeführt wird. Aber bis zu diesem Punkt? Ein langsamerer Bare-Metal-Server, der die Leistung von virt übertrifft. 8-Kern um den Faktor 5?

  1. Ist das wirklich erwartetes Verhalten von Xen?
  2. Können Sie Xen optimieren, um die Leistung für neue TCP-Verbindungen zu verbessern?
  3. Gibt es andere Virtualisierungsplattformen, die für diese Art von Anwendungsfällen besser geeignet sind?

Reproduzieren dieses Verhaltens

Als ich dies weiter untersuchte und das Problem herausfand, stellte ich fest, dass das netperf- Leistungstest-Tool das ähnliche Szenario simulieren könnte, das ich erlebe. Mit dem TCP_CRR-Test von netperf habe ich verschiedene Berichte von verschiedenen Servern (sowohl virtualisiert als auch nicht virtuell) gesammelt. Wenn Sie mit einigen Ergebnissen beitragen oder meine aktuellen Berichte einsehen möchten , lesen Sie bitte https://gist.github.com/985475

Woher weiß ich, dass dieses Problem nicht auf schlecht geschriebene Software zurückzuführen ist?

  1. Der Server wurde auf Bare-Metal-Hardware getestet und sättigt fast alle verfügbaren Kerne.
  2. Bei der Verwendung von Keep-Alive-TCP-Verbindungen wird das Problem behoben.

Warum ist das wichtig?

Bei ESN (meinem Arbeitgeber) bin ich Projektleiter von Beaconpush , einem in Java geschriebenen Comet / Web Socket-Server. Obwohl es sehr performant ist und unter optimalen Bedingungen nahezu jede Bandbreite auslasten kann, ist es immer noch darauf beschränkt, wie schnell neue TCP-Verbindungen hergestellt werden können. Das heißt, wenn Sie eine große Benutzerabwanderung haben, bei der Benutzer sehr oft kommen und gehen, müssen viele TCP-Verbindungen eingerichtet / abgebaut werden. Wir bemühen uns, diese Probleme so lange wie möglich zu lösen. Aber am Ende ist es die accept () - Performance, die unsere Kerne davon abhält, sich zu drehen, und das gefällt uns nicht.


Update 1

Jemand hat diese Frage in Hacker News gestellt , es gibt dort auch einige Fragen / Antworten. Aber ich werde versuchen, diese Frage mit Informationen auf dem neuesten Stand zu halten, die ich im Laufe der Zeit finde.

Hardware / Plattformen, auf denen ich das getestet habe:

  • EC2 mit Instanztypen c1.xlarge (8 Kerne, 7 GB RAM) und cc1.4xlarge (2x Intel Xeon X5570, 23 GB RAM). Die verwendeten AMIs waren ami-08f40561 bzw. ami-1cad5275. Jemand wies auch darauf hin, dass die "Sicherheitsgruppen" (dh die EC2-Firewall) ebenfalls Auswirkungen haben könnten. Aber für dieses Testszenario habe ich nur auf localhost versucht, externe Faktoren wie diese zu eliminieren. Ein weiteres Gerücht, das ich gehört habe, ist, dass EC2-Instanzen nicht mehr als 100.000 PPS übertragen können.
  • Zwei private virtualisierte Server, auf denen Xen ausgeführt wird. Man hatte vor dem Test keine Last, machte aber keinen Unterschied.
  • Privater dedizierter Xen-Server bei Rackspace. Über die gleichen Ergebnisse gibt.

Ich bin dabei, diese Tests erneut auszuführen und die Berichte unter https://gist.github.com/985475 auszufüllen. Wenn Sie helfen möchten, tragen Sie Ihre Zahlen ein. Es ist einfach!

(Der Aktionsplan wurde in eine separate, konsolidierte Antwort verschoben.)


3
Hervorragende Arbeit bei der Suche nach einem Problem, aber ich glaube, Sie würden auf einer Xen-spezifischen Mailingliste, einem Support-Forum oder sogar auf der Xensource-Bug-Report-Site viel besser bedient . Ich glaube, das könnte ein Planungsfehler sein - wenn Sie Ihre Anzahl von 7.000 Verbindungen * 4 Kerne / 0,80 CPU-Auslastung nehmen, erhalten Sie genau 35.000 - die Anzahl, die Sie erhalten würden, wenn 4 Kerne voll ausgelastet wären.
the-wabbit

Ah, und noch etwas: versuchen Sie es mit einer anderen (vielleicht neueren) Kernelversion für Ihren Gast, wenn Sie können.
the-wabbit

@ syneticon-dj Danke. Ich habe es auf einem cc1.4xlarge bei EC2 mit Kernel 2.6.38 ausprobiert. Ich habe einen Anstieg von ca. 10% gesehen, wenn ich mich nicht irre. Dies liegt jedoch eher an der leistungsfähigeren Hardware dieses Instanztyps.
cgbystrom

6
Vielen Dank, dass Sie die HN-Antworten auf dem neuesten Stand gehalten haben. Es ist eine großartige Frage. Ich schlage vor, den Aktionsplan in eine konsolidierte Antwort zu verschieben, da dies alles mögliche Antworten auf das Problem sind.
Jeff Atwood

@jeff Verschieben Sie den Aktionsplan und überprüfen Sie ihn.
cgbystrom

Antworten:


27

Momentan: Die Leistung kleiner Pakete ist unter Xen schlecht

(stattdessen von der Frage selbst zu einer separaten Antwort verschoben)

Laut einem Benutzer von HN (ein KVM-Entwickler?) Liegt dies an der Leistung kleiner Pakete in Xen und auch in KVM. Es ist ein bekanntes Problem mit der Virtualisierung, und laut VMWare ist dies mit ESX viel besser möglich. Er merkte auch an, dass KVM einige neue Funktionen bringt, die dies abmildern sollen ( Originalbeitrag ).

Diese Information ist etwas entmutigend, wenn sie korrekt ist. In jedem Fall probiere ich die folgenden Schritte aus, bis ein Xen-Guru eine endgültige Antwort liefert :)

Iain Kay von der Xen-Benutzer-Mailingliste hat dieses Diagramm erstellt: netperf graph Beachten Sie die TCP_CRR-Leisten, vergleichen Sie "2.6.18-239.9.1.el5" mit "2.6.39 (mit Xen 4.1.0)".

Aktueller Aktionsplan basierend auf Antworten / Antworten hier und von HN :

  1. Senden Sie dieses Problem an eine Xen-spezifische Mailingliste und den Bugzilla der Xensource, wie von syneticon-dj vorgeschlagen. In der Xen -Benutzerliste wurde eine Nachricht gepostet, die auf eine Antwort wartet.

  2. Erstellen Sie einen einfachen pathologischen Testfall auf Anwendungsebene und veröffentlichen Sie ihn.
    Ein Testserver mit Anweisungen wurde erstellt und auf GitHub veröffentlicht . Damit sollten Sie in der Lage sein, einen realistischeren Anwendungsfall im Vergleich zu netperf zu sehen.

  3. Versuchen Sie es mit einer 32-Bit-PV-Xen-Gastinstanz, da 64-Bit in Xen möglicherweise mehr Overhead verursacht. Jemand hat das auf HN erwähnt. Hat keinen Unterschied gemacht.

  4. Versuchen Sie, net.ipv4.tcp_syncookies in sysctl.conf zu aktivieren, wie von abofh für HN vorgeschlagen. Dies könnte anscheinend die Leistung verbessern, da der Handshake im Kernel stattfinden würde. Ich hatte kein Glück damit.

  5. Erhöhen Sie den Rückstand von 1024 auf etwas viel Höheres, was auch von abofh auf HN vorgeschlagen wird. Dies könnte ebenfalls hilfreich sein, da der Gast möglicherweise mehr Verbindungen akzeptieren könnte, während sein Ausführungsabschnitt von dom0 (dem Host) angegeben wird.

  6. Stellen Sie sicher, dass conntrack auf allen Rechnern deaktiviert ist, da dies die Akzeptanzrate halbieren kann (vorgeschlagen von deubeulyou). Ja, es wurde in allen Tests deaktiviert.

  7. Überprüfen Sie, ob "Listen Queue Overflow" und "Syncache Buckets Overflow" in netstat -s vorliegen (empfohlen von mike_esspe auf HN).

  8. Teilen Sie die Interrupt-Behandlung auf mehrere Kerne auf (RPS / RFS, die ich zuvor aktiviert habe, sollten dies tun, aber es könnte sich lohnen, es erneut zu versuchen). Vorgeschlagen von adamt bei HN.

  9. Deaktivieren des TCP-Segmentierungs-Offloads und der Streu- / Sammelbeschleunigung, wie von Matt Bailey vorgeschlagen. (Nicht möglich auf EC2 oder ähnlichen VPS Hosts)


2
+1 Veröffentlichen Sie auf jeden Fall die Performance-Ergebnisse, wenn Sie es herausgefunden haben!
Chrisaycock

Jemand hat mich auf Twitter wegen dieser Frage angestachelt. Leider scheint es, als ob diese Probleme bestehen bleiben. Ich habe seit letztem Jahr nicht mehr viel recherchiert. Xen hat sich in dieser Zeit möglicherweise verbessert, ich weiß es nicht. Der KVM-Entwickler erwähnte auch, dass sie solche Probleme ansprechen. Könnte es wert sein, verfolgt zu werden. Eine andere Empfehlung, die ich gehört habe, ist, OpenVZ anstelle von Xen / KVM zu verwenden, da es weniger oder gar kein Layering / Abfangen von Systemaufrufen ermöglicht.
cgbystrom

21

Anekdotisch stellte ich fest, dass das Deaktivieren der NIC-Hardwarebeschleunigung die Netzwerkleistung auf dem Xen-Controller erheblich verbessert (auch für LXC):

Scatter-Gather-Beschleunigung:

/usr/sbin/ethtool -K br0 sg off

TCP-Segmentierungs-Offload:

/usr/sbin/ethtool -K br0 tso off

Wobei br0 Ihre Bridge oder Ihr Netzwerkgerät auf dem Hypervisor-Host ist. Sie müssen dies einrichten, um es bei jedem Start auszuschalten. YMMV.


Ich unterstütze das. Ich hatte einen Windows 2003-Server unter Xen, auf dem unter Bedingungen mit hohem Durchsatz einige schreckliche Paketverlustprobleme auftraten. Das Problem ging weg, als ich TCP-Segment-Offload deaktivierte
Rupello

Vielen Dank. Ich habe den "Aktionsplan" in der ursprünglichen Frage mit Ihren Vorschlägen aktualisiert.
cgbystrom


3

Vielleicht könnten Sie ein bisschen Klarheit schaffen - haben Sie die Tests unter Xen auf Ihrem eigenen Server oder nur auf einer EC2-Instanz ausgeführt?

Accept ist nur ein weiterer Systemaufruf, und neue Verbindungen unterscheiden sich nur dadurch, dass die ersten Pakete bestimmte Flags aufweisen - ein Hypervisor wie Xen sollte definitiv keinen Unterschied feststellen. Andere Teile Ihres Setups könnten: In EC2 wäre ich zum Beispiel nicht überrascht, wenn Sicherheitsgruppen etwas damit zu tun hätten; conntrack soll außerdem die Akzeptanzrate für neue Verbindungen halbieren (PDF) .

Schließlich scheint es CPU / Kernel-Kombinationen zu geben, die auf EC2 (und wahrscheinlich auch auf Xen im Allgemeinen) eine seltsame CPU-Auslastung / ein Aufhängen verursachen, wie kürzlich von Librato berichtet wurde .


Ich habe die Frage aktualisiert und geklärt, auf welcher Hardware ich das ausprobiert habe. abofh schlug außerdem vor, das Backlog über 1024 hinaus zu erhöhen, um die Anzahl der möglichen accept () s während eines Ausführungsslices für den Gast zu beschleunigen. In Bezug auf conntrack sollte ich auf jeden Fall überprüfen, ob solche Dinge deaktiviert sind, danke. Ich habe diesen Liberato-Artikel gelesen, aber angesichts der Menge an unterschiedlicher Hardware, mit der ich das ausprobiert habe, sollte das nicht der Fall sein.
cgbystrom

0

Stellen Sie sicher, dass Sie iptables und andere Hooks im Bridging-Code in dom0 deaktiviert haben. Offensichtlich gilt dies nur für das Bridge-Networking-Xen-Setup.

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

Dies hängt von der Größe des Servers ab, aber von kleineren (4-Core-Prozessor), die Xen dom0 einen CPU-Kern zuweisen und diesen anheften. Hypervisor-Startoptionen:

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

Haben Sie versucht, ein physisches Ethernet-PCI-Gerät an domU zu übergeben? Es sollte einen schönen Leistungsschub geben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.