Der Kampf um Ressourcen, Teil 6: cpuset oder Sharing, ist nicht immer richtig

    Wenn es um Gruppen geht, stellen Red Hat-Benutzer häufig die gleiche Frage: „Ich habe eine Anwendung, die in Bezug auf Verzögerungen sehr empfindlich ist. Ist es möglich, cgroups zu verwenden, um diese Anwendung von den anderen zu isolieren, indem Sie sie an bestimmte Prozessorkerne binden? “



    Natürlich ist dies möglich. Andernfalls würden wir dieses Thema nicht zum Thema des heutigen Artikels machen.

    In der Kindheit wurde uns oft gesagt, dass Teilen gut und richtig ist. Im Großen und Ganzen so wie es ist. Aber es gibt Ausnahmen.

    Wie wir im ersten Beitrag dieser Serie geschrieben habenStandardmäßig verhält sich Red Hat Enterprise Linux 7 wie eine sphärische Großmutter. In dem Sinne, dass sie versucht, die Systemressourcen fair auf alle zu verteilen, die sie fragen. Im wirklichen Leben haben Großmütter jedoch Haustiere, die mehr bekommen. In sysadmin übersetzt bedeutet dies, dass es Situationen gibt, in denen einige Anwendungen oder Dienste wichtiger sind als andere. Daher sollte ihnen die größtmögliche Aufmerksamkeit gewidmet werden, damit sie so schnell wie möglich reagieren.

    Red Hat Enterprise Linux 7 führt dies in zwei Schritten aus:

    1. Wir isolieren einen Teil der Prozessorkerne, um sie zur ausschließlichen Verwendung einer solchen Anwendung zu übertragen.
    2. Erstellen Sie cgroups-Gruppen und Unit-Dateien, die diese Anwendung an isolierte Kernel anhängen.

    Ein kleiner Exkurs zu den Beispielen aus diesen Beiträgen


    Hat Enterprise Linux 7.4 hat die Funktionsweise von kurzlebigen Slices, wie z. B. Benutzersitzungen, geändert. Infolgedessen können sie die cgroup-Einstellungen nicht mehr im laufenden Betrieb ändern, permanente Konfigurationsänderungen vornehmen oder Drop-In-Dateien mit dem Befehl systemctl set-property erstellen. Ja, es ist eine Schande, aber die Linux-Entwicklergemeinde hat sich dazu entschlossen. Die gute Nachricht ist, dass diese Änderungen den Service nicht beeinflusst haben. Das heißt, wenn Anwendungen über Unit-Dateien gestartet und gestoppt werden (als Daemons arbeiten), funktionieren alle unsere Beispiele. Darüber hinaus ist es weiterhin möglich, mit alten Tools wie cgcreate und cgset eigene Gruppen zu erstellen und anschließend Benutzersitzungen und -prozesse in diese Gruppen zu platzieren, um CPU-Bälle und andere Steuerelemente zu verwenden. Alles ändert sich im Leben Daher können wir nur neue Techniken anpassen und erfinden. Und jetzt wenden wir uns dem heutigen Thema zu.

    Separatismus mit Isolcpus aufbauen


    Eine der wichtigsten Komponenten im Linux-Kernel ist der Process Scheduler. Wenn etwas tiefer, dann ist ein Prozess ein ausführbarer Code, der Teil einer Anwendung oder eines Dienstes ist. Tatsächlich besteht der Prozess aus einer Reihe von Anweisungen, die der Computer ausführt, um diese oder jene Arbeit zu erledigen, egal ob Siegel oder etwas ernsthafteres.

    Diese Anweisungen werden vom Zentralprozessor (auch als CPU bezeichnet) verarbeitet. Auf modernen Computern besteht eine CPU normalerweise aus mehreren Prozessoren, die als Kerne bezeichnet werden.

    Standardmäßig betrachtet der Scheduler jeden Prozessorkern als eines der Ausführungsmodule, denen neue Prozesse zugewiesen werden, sobald sie angezeigt werden. In diesem Fall versucht der Scheduler, die entstehenden Prozesse unter Berücksichtigung der Last mehr oder weniger gleichmäßig auf die Kerne zu verteilen. Leider kann dem Scheduler nicht gesagt werden, dass dieser bestimmte Prozess letztendlich eine ganze Gruppe von Prozessen hervorruft, und diese Gruppe muss isoliert von anderen Prozessen ausgeführt werden, in dem Sinne, dass sie keine gemeinsamen Prozessorkerne haben sollten.

    Aus diesem Grund müssen wir dem Planer irgendwie mitteilen, dass er keinen Teil der Prozessorkerne berührt, dh ihnen keine Prozesse gibt, die betroffen sind. Und dann werden wir selbst (oder mit Hilfe eines anderen Prozesses) diejenigen Prozesse erzwingen, die wir für notwendig halten, um vom Kernel-Scheduler isoliert zu werden. Dies kann mithilfe des isolcpus-Parameters in der Kernel-Boot-Zeile in der grub-Konfigurationsdatei erfolgen. Im folgenden Beispiel haben wir eine Maschine mit vier Kerneln, auf denen sich zwei Grub-Dateien befinden: Eine befindet sich in / etc / default und heißt grub.noiso (dies ist eine Sicherungskopie der Standardkonfiguration), die zweite befindet sich dort und heißt einfach grub grub2-mkconfig aufgegriffen. Diese zweite Datei wurde bearbeitet, um die Kernel 1-3 vom Prozess-Scheduler zu isolieren.


    WARNUNG: Unter Red Hat Enterprise Linux 7 müssen Sie die Datei grub.conf im Ordner / boot niemals manuell ändern. Nehmen Sie stattdessen die erforderlichen Änderungen in / etc / default / grub vor und erstellen Sie die Datei grub.conf mit dem entsprechenden Dienstprogramm neu. Beispiel:


    Wenn Sie den Parameter isolcpus verwenden, müssen Sie die freigegebenen Prozessorkerne durch ein Komma trennen. Die Nummerierung beginnt bei 0. Nach dem Neustart des Systems verwendet der Prozess-Scheduler diese Kerne nur für bestimmte Prozesse auf Systemebene, die auf jedem Kern vorhanden sein MÜSSEN. Um zu überprüfen, ob unsere Methode funktioniert hat, starten wir mehrere Ladevorgänge und überprüfen dann das Laden jedes Kernels mit dem Befehl top.


    Wie Sie sehen, befanden sich alle Ladeprozesse auf CPU 0, anstatt gleichmäßig auf alle vier Kerne verteilt zu sein. Also haben wir den Boot-Parameter korrekt registriert.

    Binden Sie Prozesse mit cpuset an Kernel


    Jetzt gehen wir zu Dingen über , die Sie besser nicht tun sollten, wenn Sie nicht verstehen, warum Sie dies tun, und die erst nach gründlichen Tests in der Produktion bereitgestellt werden sollten .

    Wofür sind diese Warnungen? Um die Tatsache, dass wir im Allgemeinen einfache Dinge mit dem libcgroup-Toolkit tun werden, über das in einem früheren Beitrag geschrieben wurde. Wenn Sie sich erinnern, ist dies nur eine Reihe von Befehlen zum Erstellen, Ändern und Löschen von Gruppen. Tatsächlich sind sie Teil von Red Hat Enterprise Linux 6, können aber auch auf Red Hat Enterprise Linux 7 installiert werden, obwohl diese Möglichkeit möglicherweise in Zukunft nicht mehr besteht. Erinnern Sie sich kurz an die wichtigsten Empfehlungen für die Verwendung von libcgroup:

    1. Verwenden Sie systemd, um die Gruppencontroller zu steuern, die von systemd selbst gesteuert werden (dies sind die CPU, der Speicher und die Block-E / A).
    2. Verwenden Sie die libcgroup-Tools, um alle anderen cgroup-Controller zu verwalten.
    3. Seien Sie sehr vorsichtig mit den ungeplanten Folgen Ihrer Handlungen.

    Mit dem Konzept von cpuset ist alles einfach - dies ist eine Liste von Prozessorkernen (Nummerierung, Rückruf, beginnt bei 0), die Aufgaben akzeptieren, die NUR auf diesen Kernen ausgeführt werden. Dies sind die am häufigsten verwendeten Prozessorkerne. Sie können entweder von einem Prozess-Scheduler gesteuert werden (so wird das System standardmäßig konfiguriert) oder sie können vom Scheduler isoliert werden (wie im obigen Beispiel).

    Lassen Sie uns das Verzeichnis / sys / fs / cgroup auf dem System anhand unseres Beispiels überprüfen. Wie Sie sehen, ist das cpuset-Verzeichnis bereits vorhanden, da dieser Controller Teil des Kernels ist (obwohl er nicht von systemd gesteuert wird). Da es jedoch noch keine cgroups gibt, werden in diesem Verzeichnis nur die Standardeinstellungen angezeigt.


    Vergewissern wir uns, dass das libcgroup-Toolkit auf unserem Computer installiert ist:


    Wenn es nicht installiert ist, kann dies einfach mit dem Befehl yum install libcgroup behoben werden. Auch ein Neustart ist nicht erforderlich.

    Jetzt erstelle cpuset. Dazu erstellen wir mit den folgenden Befehlen eine neue cgroup für cpuset und registrieren deren Eigenschaften:


    Mit dem Befehl cgcreate wird eine cgroup mit dem Namen testset erstellt und in den cpuset-Controller eingefügt. Dann weisen wir diesem neuen CPU-Satz den dritten Kern unserer VM zu und weisen ihm die NUMA-Zone 0. Auch wenn Ihr System NUMA nicht verwendet (und unser System es nur nicht verwendet), müssen Sie die Zone dennoch registrieren, da Sie sonst der Gruppe cgroup keine Aufgaben zuweisen können . Überprüfen Sie nun, ob das Verzeichnis testset im Dateisystem erstellt wurde, und prüfen Sie, was sich darin befindet.


    Wie Sie sehen, sind unsere Änderungen in Kraft, aber auf diesem cpuset läuft noch kein Prozess. Wie pflanzt man hier einen Prozess?

    Hierfür gibt es verschiedene Möglichkeiten:

    • Sie können die PID eines vorhandenen Prozesses in die Aufgabendatei übernehmen. Es funktioniert, aber nicht sehr hübsch.
    • Sie können cgexec verwenden und die Gruppe angeben, wenn der Prozess gestartet wird. Dies funktioniert, wenn die Anwendung kein Daemon ist. Darüber hinaus kann all dies sehr schön im Anwendungsstart-Skript geschrieben werden.
    • Für eine Anwendung, die als Dämon ausgeführt wird und systemd ausführt, können Sie eine Servicedatei erstellen.

    Schauen wir uns die cgexec-Option an.


    Wir haben foo.exe gestartet, wodurch wiederum ein untergeordneter Prozess gestartet wurde, der nur den Prozessor aktiv lädt. Die Option --sticky im Befehl cgexec besagt, dass "ein untergeordneter Prozess in derselben Gruppe wie der übergeordnete Prozess verbleiben muss". Das ist also eine wichtige Option, an die man sich erinnern muss. Jetzt sehen wir, dass sich zwei Prozesse in unserer Gruppe drehen, und wir kennen ihre PIDs. Schauen Sie sich oben an:


    Wie Sie sehen, ist CPU 3 jetzt in den Augäpfeln geladen, und der Rest kühlt sich ab.

    Und so sieht eine Unit-Datei aus, um dieselbe Anwendung wie ein systemd-Dienst auszuführen:


    Die Unit-Datei enthält drei ExecStartPre-Befehle, die die Einstellungen vornehmen, die wir bereits mit unseren Händen vorgenommen haben. Dann kommt der ExecStart-Befehl, der die Anwendung startet. Und wenn die Anwendung stoppt, bereinigt der ExecStopPost-Befehl nach sich selbst und entfernt cgroup.


    Wie Sie sehen, haben wir im letzten Beispiel eine neue cgroup mit dem Namen set1 erstellt. Wir haben dies getan, um zu zeigen, dass Sie mehrere aktive Gruppen mit derselben CPU haben können. Wem mag es sinnvoll erscheinen, im Gegenteil aber jemanden zu verwirren.

    Gut funktioniert es Sieht ja aus!


    Und jetzt werden wir die Arbeit unseres Dienstes abschließen und überprüfen, ob cgroup zerstört ist:


    ACHTUNG: cgroup-Gruppen, die mit cgcreate erstellt wurden, werden nach dem Neustart nicht gespeichert. Daher muss die Erstellung solcher Gruppen in Startskripten und Unit-Dateien vorgeschrieben werden.

    Daher gibt es in Ihrem Arsenal noch einige Tools für die Arbeit mit Gruppen. Wir hoffen, dass sie nützlich sind!

    Andere Beiträge von cgroups aus unserer Resource Fight-Reihe finden Sie unter:


    Jetzt auch beliebt: