GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum stottert mein Linux-System, wenn ich nicht kontinuierlich Caches lösche?

Es hört sich so an, als hätten Sie bereits viele der Dinge ausprobiert, die ich anfangs vorgeschlagen hätte (Änderung der Swap-Konfiguration, Änderung der I/O-Scheduler usw.).

Abgesehen von dem, was Sie bereits versucht haben, zu ändern, würde ich vorschlagen, die etwas hirntoten Standardeinstellungen für das VM-Rückschreibeverhalten zu ändern. Dies wird von den folgenden sechs sysctl-Werten verwaltet:

  • vm.dirty_ratio :Steuert, wie viele Schreibvorgänge für das Zurückschreiben anstehen müssen, bevor es ausgelöst wird. Behandelt das Rückschreiben im Vordergrund (pro Prozess) und wird als ganzzahliger Prozentsatz des Arbeitsspeichers ausgedrückt. Standardmäßig 10 % des Arbeitsspeichers
  • vm.dirty_background_ratio :Steuert, wie viele Schreibvorgänge für das Zurückschreiben anstehen müssen, bevor es ausgelöst wird. Verarbeitet das Rückschreiben im Hintergrund (systemweit) und wird als ganzzahliger Prozentsatz des Arbeitsspeichers ausgedrückt. Standardmäßig 20 % des Arbeitsspeichers
  • vm.dirty_bytes :Das gleiche wie vm.dirty_ratio , außer als Gesamtzahl von Bytes ausgedrückt. Entweder dieses oder vm.dirty_ratio verwendet, was zuletzt geschrieben wurde.
  • vm.dirty_background_bytes :Das gleiche wie vm.dirty_background_ratio , außer als Gesamtzahl von Bytes ausgedrückt. Entweder dieses oder vm.dirty_background_ratio verwendet, was zuletzt geschrieben wurde.
  • vm.dirty_expire_centisecs :Wie viele Hundertstelsekunden müssen vergehen, bevor das ausstehende Zurückschreiben beginnt, wenn die obigen vier sysctl-Werte es nicht bereits auslösen würden. Der Standardwert ist 100 (eine Sekunde).
  • vm.dirty_writeback_centisecs :Wie oft (in Hundertstelsekunden) der Kernel schmutzige Seiten für das Zurückschreiben auswertet. Der Standardwert ist 10 (eine Zehntelsekunde).

Mit den Standardwerten wird der Kernel also jede Zehntelsekunde Folgendes tun:

  • Schreiben Sie alle geänderten Seiten in den dauerhaften Speicher, wenn sie zuletzt vor mehr als einer Sekunde geändert wurden.
  • Alle modifizierten Seiten für einen Prozess ausschreiben, wenn die Gesamtmenge des modifizierten Speichers, der nicht ausgeschrieben wurde, 10 % des RAM überschreitet.
  • Schreiben Sie alle geänderten Seiten im System heraus, wenn die Gesamtmenge des geänderten Speichers, der nicht herausgeschrieben wurde, 20 % des RAM überschreitet.

Es sollte also ziemlich einfach zu erkennen sein, warum die Standardwerte Probleme für Sie verursachen könnten, da Ihr System möglicherweise versucht, bis zu 4 Gigabyte zu schreiben von Daten in persistenter Speicherung jedes Zehntel einer Sekunde.

Der allgemeine Konsens besteht heutzutage darin, vm.dirty_ratio anzupassen 1 % des RAM und vm.dirty_background_ratio sein auf 2 %, was bei Systemen mit weniger als etwa 64 GB RAM zu einem Verhalten führt, das dem ursprünglich beabsichtigten entspricht.

Einige andere Dinge, die Sie sich ansehen sollten:

  • Versuchen Sie, den vm.vfs_cache_pressure zu erhöhen sysctl ein wenig. Dies steuert, wie aggressiv der Kernel Speicher aus dem Dateisystem-Cache zurückfordert, wenn er RAM benötigt. Der Standardwert ist 100, senken Sie ihn nicht auf einen Wert unter 50 (Sie werden richtig schlechtes Verhalten bekommen, wenn Sie unter 50 gehen, einschließlich OOM-Bedingungen), und erhöhen Sie es nicht auf viel mehr als etwa 200 (viel höher, und der Kernel wird Zeit verschwenden, indem er versucht, Speicher zurückzugewinnen, den er wirklich nicht kann). Ich habe festgestellt, dass das Erhöhen auf 150 die Reaktionsfähigkeit tatsächlich sichtbar verbessert, wenn Sie über einen relativ schnellen Speicher verfügen.
  • Versuchen Sie, den Overcommit-Modus des Speichers zu ändern. Dies kann durch Ändern des Werts von vm.overcommit_memory erfolgen sysctl. Standardmäßig verwendet der Kernel einen heuristischen Ansatz, um vorherzusagen, wie viel RAM er sich tatsächlich leisten kann. Wenn Sie dies auf 1 setzen, wird die Heuristik deaktiviert und der Kernel angewiesen, sich so zu verhalten, als hätte er unendlichen Speicher. Wenn Sie dies auf 2 setzen, wird der Kernel angewiesen, nicht mehr Speicher als die Gesamtmenge an Auslagerungsspeicher auf dem System plus einen Prozentsatz des tatsächlichen RAM (gesteuert durch vm.overcommit_ratio ).
  • Versuchen Sie, vm.page-cluster zu optimieren sysctl. Dies steuert, wie viele Seiten gleichzeitig ein- oder ausgelagert werden (es handelt sich um einen logarithmischen Basis-2-Wert, sodass der Standardwert von 3 in 8 Seiten übersetzt wird). Wenn Sie tatsächlich tauschen, kann dies dazu beitragen, die Leistung beim Ein- und Auslagern von Seiten zu verbessern.

Das Problem wurde gefunden!

Es stellt sich heraus, dass es sich um ein Leistungsproblem im Memory Reclaimer von Linux handelt, wenn es eine große Anzahl von Containern/Speicher-Cgroups gibt. (Haftungsausschluss:Meine Erklärung könnte fehlerhaft sein, ich bin kein Kernel-Entwickler.) Das Problem wurde in 4.19-rc1+ in diesem Patch-Set behoben:

Dieses Patchset löst das Problem mit dem langsamen Shrink_slab(), das auf Maschinen mit vielen Shrinkern und Speicher-Cgroups (d. h. mit vielen Containern) auftritt. Das Problem ist, dass die Komplexität von Shrink_slab() O(n^2) ist und mit dem Wachstum der Containerzahlen zu schnell wächst.

Lassen Sie uns 200 Container haben, und jeder Container hat 10 Mounts und 10cgroups. Alle Container-Tasks sind isoliert und berühren fremde Container-Mounts nicht.

Im Fall einer globalen Rückforderung muss eine Aufgabe alle Memcgs durchlaufen und alle Memcg-fähigen Shrinker für alle aufrufen. Das bedeutet, dass der Task 200 * 10 =2000 Shrinker für jedes Memcg besuchen muss, und da es 2000 Memcgs gibt, sind die Gesamtaufrufe von do_shrink_slab() 2000 * 2000 =4000000.

Mein System war besonders stark betroffen, da ich eine große Anzahl von Containern betreibe, was wahrscheinlich die Ursache für das Auftreten des Problems war.

Meine Schritte zur Fehlerbehebung, falls sie für jemanden hilfreich sind, der ähnliche Probleme hat:

  1. Beachten Sie kswapd0 eine Menge CPU verwenden, wenn mein Computer stottert
  2. Versuchen Sie, Docker-Container zu stoppen und den Speicher erneut zu füllen → der Computer stottert nicht!
  3. Führen Sie ftrace aus (nach Julia Evans großartigem Erklärungs-Blog), um eine Spur zu bekommen, siehe diesen kswapd0 neigt dazu, in shrink_slab hängen zu bleiben , super_cache_count , und list_lru_count_one .
  4. Google shrink_slab lru slow , finden Sie das Patchset!
  5. Wechseln Sie zu Linux 4.19-rc3 und überprüfen Sie, ob das Problem behoben ist.

Linux
  1. Linux – Wie startet Gnome ohne Root-Rechte neu?

  2. Linux – Warum funktioniert Setuid nicht?

  3. Linux – Warum dauert es so lange, einen USB-Stick zu erkennen?

  4. 12 Gründe, warum jeder Linux-Systemadministrator faul sein sollte

  5. Besteht das Problem der Donnernden Herde unter Linux noch?

Linux – Warum erlaubt Linux „init=/bin/bash“?

Linux – Warum funktioniert Locale Es_mx, aber nicht Es?

Warum heizt Linux meinen Computer auf?

Warum ist Linux Unix-ähnlich, wenn sein Kernel monolithisch ist?

Protokolliert Linux normalerweise Systemtemperaturdaten?

Wie verwendet Linux eine Echtzeituhr?