Ich habe eine Ubuntu-VM, die in Ubuntu-basiertem Xen XCP ausgeführt wird. Dahinter befindet sich ein benutzerdefinierter FCGI-basierter HTTP-Dienst nginx
.
Unter Last ist ab
der erste CPU-Kern gesättigt und der Rest ist unterlastet.
In /proc/interrupts
dem sehe ich CPU0 dient eine Größenordnung mehr Unterbrechungen als jeder anderer Kern. Die meisten von ihnen kommen aus eth1
.
Kann ich irgendetwas tun, um die Leistung dieser VM zu verbessern? Gibt es eine Möglichkeit, Interrupts gleichmäßiger auszugleichen?
Gory Details:
$ uname -a Linux MYHOST 2.6.38-15-virtual # 59-Ubuntu SMP Fr 27 Apr 16:40:18 UTC 2012 i686 i686 i386 GNU / Linux $ lsb_release -a Es sind keine LSB-Module verfügbar. Händler-ID: Ubuntu Beschreibung: Ubuntu 11.04 Veröffentlichung: 11.04 Codename: natty $ cat / proc / interrupts CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7 283: 113720624 0 0 0 0 0 0 0 xen-dyn-event eth1 284: 1 0 0 0 0 0 0 0 xen-dyn-event eth0 285: 2254 0 0 3873799 0 0 0 0 xen-dyn-event blkif 286: 23 0 0 0 0 0 0 0 xen-dyn-event hvc_console 287: 492 42 0 0 0 0 0 295324 xen-dyn-event xenbus 288: 0 0 0 0 0 0 0 222294 xen-percpu-ipi callfuncsingle7 289: 0 0 0 0 0 0 0 0 xen-percpu-virq debug7 290: 0 0 0 0 0 0 0 151302 xen-percpu-ipi callfunc7 291: 0 0 0 0 0 0 0 3236015 xen-percpu-ipi resched7 292: 0 0 0 0 0 0 0 60064 xen-percpu-ipi spinlock7 293: 0 0 0 0 0 0 0 12355510 xen-percpu-virq timer7 294: 0 0 0 0 0 0 803174 0 xen-percpu-ipi callfuncsingle6 295: 0 0 0 0 0 0 0 0 xen-percpu-virq debug6 296: 0 0 0 0 0 0 60027 0 xen-percpu-ipi callfunc6 297: 0 0 0 0 0 0 5374762 0 xen-percpu-ipi resched6 298: 0 0 0 0 0 0 64976 0 xen-percpu-ipi spinlock6 299: 0 0 0 0 0 0 15294870 0 xen-percpu-virq timer6 300: 0 0 0 0 0 264441 0 0 xen-percpu-ipi callfuncsingle5 301: 0 0 0 0 0 0 0 0 xen-percpu-virq debug5 302: 0 0 0 0 0 79324 0 0 xen-percpu-ipi callfunc5 303: 0 0 0 0 0 3468144 0 0 xen-percpu-ipi resched5 304: 0 0 0 0 0 66269 0 0 xen-percpu-ipi spinlock5 305: 0 0 0 0 0 12778464 0 0 xen-percpu-virq timer5 306: 0 0 0 0 844591 0 0 0 xen-percpu-ipi callfuncsingle4 307: 0 0 0 0 0 0 0 0 xen-percpu-virq debug4 308: 0 0 0 0 75293 0 0 0 xen-percpu-ipi callfunc4 309: 0 0 0 0 3482146 0 0 0 xen-percpu-ipi resched4 310: 0 0 0 0 79312 0 0 0 xen-percpu-ipi spinlock4 311: 0 0 0 0 21642424 0 0 0 xen-percpu-virq timer4 312: 0 0 0 449141 0 0 0 0 xen-percpu-ipi callfuncsingle3 313: 0 0 0 0 0 0 0 0 xen-percpu-virq debug3 314: 0 0 0 95405 0 0 0 0 xen-percpu-ipi callfunc3 315: 0 0 0 3802992 0 0 0 0 xen-percpu-ipi resched3 316: 0 0 0 76607 0 0 0 0 xen-percpu-ipi spinlock3 317: 0 0 0 16439729 0 0 0 0 xen-percpu-virq timer3 318: 0 0 876383 0 0 0 0 0 xen-percpu-ipi callfuncsingle2 319: 0 0 0 0 0 0 0 0 xen-percpu-virq debug2 320: 0 0 76416 0 0 0 0 0 xen-percpu-ipi callfunc2 321: 0 0 3422476 0 0 0 0 0 xen-percpu-ipi resched2 322: 0 0 69217 0 0 0 0 0 xen-percpu-ipi spinlock2 323: 0 0 10247182 0 0 0 0 0 xen-percpu-virq timer2 324: 0 393514 0 0 0 0 0 0 xen-percpu-ipi callfuncsingle1 325: 0 0 0 0 0 0 0 0 xen-percpu-virq debug1 326: 0 95773 0 0 0 0 0 0 xen-percpu-ipi callfunc1 327: 0 3551629 0 0 0 0 0 0 xen-percpu-ipi resched1 328: 0 77823 0 0 0 0 0 0 xen-percpu-ipi spinlock1 329: 0 13784021 0 0 0 0 0 0 xen-percpu-virq timer1 330: 730435 0 0 0 0 0 0 0 xen-percpu-ipi callfuncsingle0 331: 0 0 0 0 0 0 0 0 xen-percpu-virq debug0 332: 39649 0 0 0 0 0 0 0 xen-percpu-ipi callfunc0 333: 3607120 0 0 0 0 0 0 0 xen-percpu-ipi resched0 334: 348740 0 0 0 0 0 0 0 xen-percpu-ipi spinlock0 335: 89912004 0 0 0 0 0 0 0 xen-percpu-virq timer0 NMI: 0 0 0 0 0 0 0 0 Nicht maskierbare Interrupts LOC: 0 0 0 0 0 0 0 0 Lokale Timer-Interrupts SPU: 0 0 0 0 0 0 0 0 Falsche Interrupts PMI: 0 0 0 0 0 0 0 0 Leistungsüberwachungs-Interrupts IWI: 0 0 0 0 0 0 0 0 0 IRQ-Arbeitsunterbrechungen RES: 3607120 3551629 3422476 3802992 3482146 3468144 5374762 3236015 Interrupts neu planen CAL: 770084 489287 952799 544546 919884 343765 863201 373596 Funktionsaufruf-Interrupts TLB: 0 0 0 0 0 0 0 0 TLB-Abschüsse TRM: 0 0 0 0 0 0 0 0 Thermische Ereignisunterbrechungen THR: 0 0 0 0 0 0 0 0 Schwellenwert-APIC-Interrupts MCE: 0 0 0 0 0 0 0 0 Maschinenprüfungsausnahmen MCP: 0 0 0 0 0 0 0 0 Maschinenprüfungen ERR: 0 MIS: 0
linux
ubuntu
performance-tuning
high-load
interrupts
Alexander Gladysh
quelle
quelle
eth1
?Antworten:
Schauen Sie in das
/proc/irq/283
Verzeichnis. Es gibt einesmp_affinity_list
Datei, die zeigt, welche CPUs den 283-Interrupt erhalten. Für Sie enthält diese Datei wahrscheinlich "0" (undsmp_affinity
wahrscheinlich "1").Sie können den CPU-Bereich in die
smp_affinity_list
Datei schreiben :Oder Sie können eine Bitmaske schreiben, wobei jedes Bit einer CPU entspricht, um
smp_affinity
:Allerdings irqbalance ist bekannt , seine eigene Vorstellung von dem, was jede Affinität Interrupt haben sollte, und es könnte Ihren Updates zurück. Daher ist es am besten, wenn Sie irqbalance nur vollständig deinstallieren. Oder stoppen Sie es zumindest und deaktivieren Sie es beim Neustart.
Wenn Sie auch ohne Ungleichgewicht
smp_affinity
nach einem Neustart für Interrupt 283 ungerade werden , müssen Sie die CPU-Affinität in einem Ihrer Startskripte manuell aktualisieren.quelle
irqbalance
läuft schon. Vielleicht ist es nicht richtig konfiguriert? Wie überprüfe ich das?/proc/irq/283/smp_affinity
hat01
jetzt drin (niemand hat das Zeug auf dieser Maschine nach meinem besten Wissen geändert - also muss dies die Systemvorgabe sein).irqbalance
(viaENABLED=0
in/etc/default/irqbalance
) hilft nicht. Nach dem Neustartirqbalance
iststop/waiting
, ist aber/proc/irq/283/smp_affinity
noch01
.Wenn Sie das richtige Intel NIC-Modell haben, können Sie die Leistung erheblich verbessern.
Um den ersten Absatz zu zitieren:
Siehe: Zuweisen von Interrupts zu Prozessorkernen mithilfe eines Intel® 82575/82576- oder 82598/82599-Ethernet-Controllers
quelle
Tatsächlich wird empfohlen, insbesondere bei sich wiederholenden Prozessen über einen kurzen Zeitraum, dass alle von einer Gerätewarteschlange generierten Unterbrechungen von derselben CPU anstatt von IRQ-Balancing behandelt werden. Daher wird eine bessere Leistung erzielt, wenn eine einzelne CPU den eth1-Interrupt behandelt *** Ausnahme unten angegeben
Die oben verlinkte Quelle stammt aus dem Linux-Symposium, und ich empfehle Ihnen, die paar Absätze zu SMP IRQ Affinity durchzulesen, da sie Sie effektiver überzeugen als dieser Beitrag.
Warum?
Denken Sie daran, dass jeder Prozessor seinen eigenen Cache hat, abgesehen davon, dass er auf den Hauptspeicher zugreifen kann. Schauen Sie sich dieses Diagramm an . Wenn ein Interrupt ausgelöst wird, muss ein CPU-Kern die Anweisungen abrufen, um den Interrupt aus dem Hauptspeicher zu behandeln. Dies dauert viel länger, als wenn sich die Anweisungen im Cache befinden. Sobald ein Prozessor eine Aufgabe ausgeführt hat, befinden sich diese Anweisungen im Cache. Angenommen, derselbe CPU-Kern verarbeitet fast immer denselben Interrupt. Die Interrupt-Handler-Funktion verlässt den CPU-Kern-Cache wahrscheinlich nicht und erhöht die Kernel-Leistung.
Wenn IRQ ausgeglichen ist, kann es alternativ die Unterbrechung so zuweisen, dass sie ständig von einer anderen CPU behandelt wird. Dann hat der neue CPU-Kern wahrscheinlich nicht die Interrupt-Handler-Funktion im Cache, und es wird eine lange Zeit erforderlich sein, um den richtigen Handler von main zu erhalten Erinnerung.
Ausnahme : Wenn Sie eth1-Interrupt selten verwenden, was bedeutet, dass genügend Zeit vergeht, dass der Cache durch andere Aufgaben überschrieben wird, was bedeutet, dass Daten zeitweise mit langen Zeiträumen dazwischen über diese Schnittstelle kommen ... dann werden Sie diese Vorteile höchstwahrscheinlich nicht sehen denn sie sind, wenn Sie einen Prozess mit hoher Frequenz verwenden.
Fazit
Wenn Ihr Interrupt sehr häufig auftritt, binden Sie diesen Interrupt nur an eine bestimmte CPU. Diese Konfiguration lebt bei
oder
Siehe den letzten Absatz in der SMP IRQ-Affinität Abschnitt aus der oben verlinkten Quelle, der Anweisungen enthält.
Alternative
Sie können die Häufigkeit ändern, mit der das Interrupt-Flag ausgelöst wird, indem Sie entweder die MTU-Größe (Jumbo-Frames) erhöhen, wenn das Netzwerk dies zulässt, oder das Flag ändern, nachdem eine größere Anzahl von Paketen empfangen wurde, anstatt bei jedem Paket ODER die Auszeit, also Interrupt nach einer bestimmten Zeit auslösen. Vorsicht bei der Zeitoption, da Ihre Puffergröße möglicherweise voll ist, bevor die Zeit abläuft. Dies kann mit dem in der verknüpften Quelle beschriebenen ethtool erfolgen .
Diese Antwort nähert sich der Länge, in der die Leute sie nicht lesen, so dass ich nicht ins Detail gehen werde, aber abhängig von Ihrer Situation gibt es viele Lösungen ... überprüfen Sie die Quelle :)
quelle