CPU-Affinität verstehen und Prozesspriorität mit nice und renice setzen

Verwenden Sie Linux `taskset`, `nice` und `renice`, um CPU-Affinität und Prozesspriorität zu optimieren, ohne kritische Arbeiten zu beeinträchtigen.

CPU-Affinität verstehen und Prozesspriorität mit nice und renice setzen

Wenn ein Linux-Host ausgelastet ist, benötigen Sie möglicherweise mehr Kontrolle als „den Scheduler entscheiden lassen“. Die CPU-Affinität bestimmt, wo ein Prozess ausgeführt werden kann, während nice und renice beeinflussen, wie stark er um CPU-Zeit konkurriert.

Diese Anleitung zeigt, wie Sie taskset, nice und renice mit praktischen Beispielen und den zu beachtenden Kompromissen verwenden, bevor Sie Produktionsworkloads ändern.

CPU-Affinität: Binden von Prozessen an bestimmte Kerne

Die CPU-Affinität ist ein Mechanismus, der es dem Betriebssystem ermöglicht, einen Prozess oder Thread an eine bestimmte CPU oder eine Gruppe von CPUs zu binden. Wenn ein Prozess an einen CPU-Kern gebunden ist, wird er nur auf diesem Kern ausgeführt. Dies hat mehrere Auswirkungen auf die Leistung:

  • Reduzierte Cache-Invalidierung: Moderne CPUs haben mehrstufige Caches (L1, L2, L3), die häufig aufgerufene Daten speichern. Wenn ein Prozess zwischen verschiedenen CPU-Kernen wechselt, werden seine Daten im Cache des vorherigen Kerns ungültig, und neue Daten müssen für den neuen Kern abgerufen werden. Das Binden eines Prozesses an einen einzelnen Kern stellt sicher, dass seine Daten im Cache dieses Kerns bleiben, was zu schnelleren Zugriffszeiten führt.
  • Minimierte Kontextwechsel: Wenn der Scheduler entscheidet, einen anderen Prozess auf einem Kern auszuführen, wird der Zustand des aktuellen Prozesses gespeichert (Kontextwechsel) und der Zustand des neuen Prozesses geladen. Wenn ein Prozess häufig zwischen Kernen wechselt, kann sich der Overhead dieser Kontextwechsel summieren. Die CPU-Affinität kann diesen Overhead reduzieren, indem der Prozess auf demselben Kern gehalten wird.
  • NUMA-Architekturen: In Non-Uniform Memory Access (NUMA)-Systemen variieren die Speicherzugriffszeiten je nach CPU-Kern und seiner Nähe zum Speichercontroller. Das Binden eines Prozesses an einen bestimmten Kern kann auch sicherstellen, dass er auf lokalen Speicher zugreift, was die Latenz reduziert.

So legen Sie die CPU-Affinität fest

Während der Linux-Kernel die CPU-Affinität oft automatisch verwaltet, können Administratoren sie manuell beeinflussen. Das wichtigste Werkzeug dafür ist taskset.

Verwendung von taskset

Der Befehl taskset ermöglicht es Ihnen, eine CPU-Affinitätsmaske für einen laufenden Prozess abzurufen oder festzulegen oder einen neuen Befehl mit einer bestimmten Affinität zu starten.

Syntax:

  • So zeigen Sie die CPU-Affinität eines laufenden Prozesses an:

    taskset -p <PID>
    
  • So legen Sie die CPU-Affinität eines laufenden Prozesses fest:

    taskset -p <mask> <PID>
    

    Die <mask> ist eine hexadezimale Zahl, die eine Bitmaske der erlaubten CPUs darstellt. Zum Beispiel bedeutet 0x1 (binär 0001) CPU 0, 0x2 (binär 0010) CPU 1, 0x3 (binär 0011) CPUs 0 und 1, und so weiter.

  • So starten Sie einen neuen Befehl mit einer bestimmten CPU-Affinität:

    taskset -c <cpu_list> <command>
    

    Die <cpu_list> ist eine durch Kommas getrennte Liste von CPU-IDs oder Bereichen (z.B. 0, 0-3, 1,3).

Beispiel:

Angenommen, Sie möchten eine Rechenaufgabe my_program ausführen und sie an CPU-Kern 3 binden:

taskset -c 3 ./my_program

Wenn my_program bereits mit der PID 12345 läuft und Sie es mit einer Affinitätsmaske einschränken möchten:

taskset -p 1 12345

Dieser Befehl verwendet eine hexadezimale Maske, also bedeutet 1 CPU 0. Um den Prozess auf CPU 1 zu verschieben, verwenden Sie -c mit CPU-Nummern:

taskset -cp 1 12345

Tipp: Sie können die Anzahl der verfügbaren CPUs mit nproc oder durch Überprüfen von /proc/cpuinfo ermitteln.

Warnung: Das falsche Setzen der CPU-Affinität kann zu Leistungseinbußen führen. Es ist am besten, Ihre Anwendung mit und ohne Affinitätseinstellungen zu benchmarken, um Vorteile zu bestätigen.

Prozessprioritätsverwaltung mit nice und renice

Während die CPU-Affinität bestimmt, wo ein Prozess läuft, bestimmt die Prozesspriorität, wie viel CPU-Zeit er im Verhältnis zu anderen Prozessen erhält. Linux verwendet ein Konzept der „Niceness“, um die Scheduling-Priorität zu steuern. Der Niceness-Wert reicht von -20 (höchste Priorität, meiste CPU-Zeit) bis +19 (niedrigste Priorität, wenigste CPU-Zeit). Der Standard-Niceness-Wert für Prozesse ist 0.

Ein höherer Niceness-Wert bedeutet, dass der Prozess „netter“ zu anderen Prozessen ist und ihnen mehr CPU-Zeit überlässt. Umgekehrt bedeutet ein niedrigerer Niceness-Wert, dass der Prozess weniger „nett“ ist und versucht, mehr CPU-Zeit zu beanspruchen.

Der Befehl nice

Der Befehl nice wird verwendet, um ein Programm mit einem geänderten Niceness-Level auszuführen. Er wird typischerweise beim Starten eines neuen Prozesses verwendet.

Syntax:

nice -n <niceness_level> <command>
  • -n <niceness_level>: Gibt den Niceness-Wert an (Standard ist 10, wenn nicht angegeben).

Beispiel:

Um my_background_task mit niedriger Priorität (hoher Niceness-Wert von 15) auszuführen:

nice -n 15 my_background_task

Um my_critical_app mit hoher Priorität (niedriger Niceness-Wert von -10) auszuführen:

nice -n -10 my_critical_app

Wichtiger Hinweis: Nur der Root-Benutzer kann einen negativen Niceness-Wert zuweisen (Priorität erhöhen). Normale Benutzer können den Niceness-Wert ihrer eigenen Prozesse nur erhöhen (Priorität verringern).

Der Befehl renice

Der Befehl renice wird verwendet, um den Niceness-Level eines oder mehrerer bereits laufender Prozesse zu ändern.

Syntax:

renice -n <niceness_level> -p <PID>
  • -n <niceness_level>: Der neue Niceness-Wert.
  • -p <PID>: Die Prozess-ID(s) des/der zu ändernden Prozesse(s).

Beispiel:

Um die Priorität von Prozess 12345 zu verringern (Niceness erhöhen) auf 10:

renice -n 10 -p 12345

Um die Priorität von Prozess 54321 zu erhöhen (Niceness verringern) auf -5 (erfordert Root-Rechte):

sudo renice -n -5 -p 54321

renice kann auch Prozesse nach Benutzer (-u) oder Prozessgruppe (-g) ansprechen.

Beispiel:

Um alle Prozesse des Benutzers www-data auf einen Niceness-Wert von 5 zu setzen:

sudo renice -n 5 -u www-data

Tipp: Verwenden Sie top oder htop, um den Niceness-Wert (Spalte NI) laufender Prozesse anzuzeigen und Kandidaten für Prioritätsanpassungen zu identifizieren.

Warnung: Das Vergeben einer sehr hohen Priorität (niedriger Niceness-Wert) an einen Prozess kann andere Prozesse aushungern und das System unresponsive machen. Verwenden Sie dies mit Vorsicht, insbesondere auf Produktionssystemen.

Praktische Szenarien und Best Practices

CPU-Affinitäts-Szenarien:

  • Datenbankserver: Das Binden von Datenbankprozessen an bestimmte Kerne kann die Abfrageleistung verbessern, indem sichergestellt wird, dass Daten im CPU-Cache bleiben.
  • Hochfrequenzhandelsanwendungen: Diese erfordern oft minimale Latenz und vorhersagbare Leistung, was die CPU-Bindung entscheidend macht.
  • Virtualisierungs-Hosts: Um bestimmte Kerne für virtuelle Maschinen oder den Host selbst zu dedizieren, was die Isolation und Leistung verbessert.

Prozessprioritäts-Szenarien:

  • Batch-Jobs/Hintergrundaufgaben: Diese können mit einem hohen Niceness-Wert (nice -n 15) ausgeführt werden, damit sie nicht mit interaktiven Benutzeraufgaben oder kritischen Diensten interferieren.
  • Interaktive Anwendungen: Sicherstellen, dass Desktop-Anwendungen oder Shells reaktionsfähig bleiben, indem Hintergrundaufgaben nicht alle CPU-Ressourcen verbrauchen.
  • Notfall-Ressourcenzuweisung: In seltenen Fällen, wenn ein kritischer Systemprozess kämpft, kann seine Priorität vorübergehend mit renice (als Root) erhöht werden.

Best Practices:

  1. Zuerst benchmarken: Messen Sie immer die Leistung vor und nach der Anwendung von CPU-Affinitäts- oder Prioritätsänderungen. Gewinne sind nicht immer garantiert und können anwendungsabhängig sein.
  2. Verstehen Sie Ihre Hardware: Seien Sie sich Ihrer CPU-Topologie (Kerne, Sockets, NUMA-Knoten) bewusst, wenn Sie die CPU-Affinität einstellen.
  3. Verwenden Sie top/htop: Überwachen Sie CPU-Auslastung, Niceness-Werte und Prozesszustände, um Leistungsprobleme zu identifizieren und Änderungen zu testen.
  4. Root-Rechte für Prioritätserhöhung: Denken Sie daran, dass nur Root den Niceness-Wert verringern (Priorität erhöhen) kann. Verwenden Sie diese Macht mit Bedacht.
  5. Beginnen Sie konservativ: Beginnen Sie bei Prioritätsanpassungen mit moderaten Niceness-Werten (z.B. 5, 10), bevor Sie zu Extremen (-20 oder +19) gehen.
  6. Berücksichtigen Sie NUMA-Bewusstsein: Für NUMA-Systeme bieten Werkzeuge wie numactl erweiterte Kontrolle über CPU- und Speicherbindung.

Fazit

Verwenden Sie CPU-Affinität, wenn die Platzierung wichtig ist, wie bei NUMA-empfindlichen Diensten oder isolierten Batch-Jobs. Verwenden Sie nice und renice, wenn das Problem die Scheduling-Priorität ist. Beginnen Sie mit kleinen Änderungen, bevorzugen Sie taskset -c für lesbare CPU-Listen, und benchmarken Sie, bevor Sie eine Tuning-Regel dauerhaft machen.