Ich habe ein großes System mit vielen festplattengebundenen Diensten. Sie funktionieren mit der Verwendung des Block-Cache viel besser.
Daneben laufen auch einige Backup-Prozesse.
Ich weiß, wie sie den Blockcache verwenden sollten: Das sollten sie auf keinen Fall.
Die Sicherung erfolgt durch das Kopieren eines Blockgeräts auf ein anderes mit einembuffer
Befehl. Die Wahrscheinlichkeit, dass dafür ein Caching erforderlich wäre, liegt praktisch bei Null.
Wenn das Backup jedoch ausgeführt wird, verschlechtert es die normalen Dienste.ionice
hilft nicht viel - das Problem ist nicht die IO-Priorität, sondern dass es den Block-Cache mit nicht benötigten Daten überschreibt.
Kann ich diesen Befehl irgendwie so einrichten, buffer
dass der Blockcache überhaupt nicht verwendet wird?
Es kopiert LVM-Volumes auf ein anderes, falls das wichtig ist.
Antwort1
Ich habe gefundennocache
Werkzeug für die Aufgabe.
Im Allgemeinen ist dies unter Linux nicht möglich: Es gibt keine solche Option oder Flagge oder irgendetwas, das für einenVerfahren.
Allerdingsposix_fadvise(...)
Der Aufruf kann verwendet werden, um das Block-/Puffercache-Subsystem zu informieren, wenn ein aufeinanderfolgender Lese-/Schreibvorgang erwartet wird. Er POSIX_FADV_DONTNEED
gibt dem Kernel die „zusätzliche Information“, dass er sie nicht zwischenspeichern soll, da sie in naher Zukunft nicht erneut gelesen werden.
nocache
fängt alle wichtigen Dateioperationen mithilfe einer durch die Umgebungsvariable posix_fadvise(...)
eingefügten gemeinsam genutzten Bibliothek ab.LD_PRELOAD
Wie der Name schon sagt, ist es nur ein Ratschlag; meine Experimente zeigen jedoch eineriesigLeistungsverbesserung (tatsächlich können andere wichtige Aufgaben parallel zu den Backups im Hintergrund ausgeführt werden, ohne dass für die Endbenutzer ein sichtbarer Leistungsrückgang auftritt).
Antwort2
Werkzeuge wie nocache
sind eigentlichnichtdie passende Lösung. Um zu zitierennocacheQuelle:
Was dieses Werkzeug istnichtgut für:
- Steuern der Nutzung Ihres Seitencaches
- Warum glauben Sie, dass irgendein beliebiges Tool, das Sie auf GitHub gefunden haben, besser sein kann als der Linux-Kernel?
- Schutz vor Cache-Thrashing
- Verwenden Sie cgroups, um die Speichermenge eines Prozesses zu begrenzen. Siehe unten oder suchen Sie im Internet. Dies ist weithin bekannt, funktioniert zuverlässig und führt nicht zu Leistungseinbußen oder potenziell gefährlichem Verhalten wie dieses Tool.
Verwenden Sie also cgroups (genauer gesagt, im Jahr 2023 auf jeden Fall cgroupsv2, wann immer möglich), um die Cache-Menge zu begrenzen, die Ihr Prozess verwenden kann (und damit die Cache-Menge zu begrenzen, die er verlagern kann):
So führen Sie einen Prozess und seine untergeordneten Prozesse in einer speicherbegrenzten Kontrollgruppe aus
Tun Sie dies, wenn Sie beispielsweise eine Sicherung ausführen möchten, Ihr System aber nicht durch eine Überlastung des Seitencaches langsamer werden soll.
Wenn Sie systemd verwenden
Wenn Ihre Distribution verwendet
systemd
, ist dies sehr einfach. Systemd ermöglicht die Ausführung eines Prozesses (und seiner Unterprozesse) in einem „Bereich“, also einer Kontrollgruppe, und Sie können Parameter angeben, die in Kontrollgruppen-Grenzen übersetzt werden.Wenn ich meine Backups ausführe, mache ich Folgendes:
$ systemd-run --scope --property=MemoryLimit=500M -- backup command
( MemoryMax
für v2)
Dies hat zur Folge, dass der Cache-Speicherplatz zusätzlich auf maximal 500 MiB begrenzt bleibt:
Vor:
$ free -h total used free shared buff/cache available Mem: 7.5G 2.4G 1.3G 1.0G 3.7G 3.7G Swap: 9.7G 23M 9.7G
Während (beachten Sie, dass Buff/Cache nur um ~300 MiB ansteigt):
$ free -h total used free shared buff/cache available Mem: 7.5G 2.5G 1.0G 1.1G 4.0G 3.6G Swap: 9.7G 23M 9.7G
Wie funktioniert das?
Verwenden Sie es
systemd-cgls
, um die von Systemd erstellten Kontrollgruppen aufzulisten. Auf meinem System erstellt der obige Befehl eine Gruppe namens „run-u467.scope
übergeordnetesystem.slice
Gruppe“. Sie können ihre Speichereinstellungen folgendermaßen überprüfen:$ mount | grep cgroup | grep memory cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec latime,memory) $ cat /sys/fs/cgroup/memory/system.slice/run-u467.scope/memory.limit_in_bytes 524288000