Beschränken Sie die Größe des Puffercaches unter Linux

25

Gibt es eine Möglichkeit, den Linux-Kernel anzuweisen, nur einen bestimmten Prozentsatz des Speichers für den Puffercache zu verwenden? Ich weiß, /proc/sys/vm/drop_cachesdass der Cache vorübergehend geleert werden kann, aber gibt es eine permanente Einstellung, die verhindert, dass er auf mehr als z. B. 50% des Hauptspeichers anwächst?

Der Grund, warum ich dies tun möchte, ist, dass ich einen Server mit einem Ceph-OSD habe, der ständig Daten von der Festplatte bereitstellt und es schafft, innerhalb weniger Stunden den gesamten physischen Speicher als Puffer-Cache zu nutzen. Gleichzeitig muss ich Anwendungen ausführen, die eine große Menge (mehrere 10 GB) physischen Arbeitsspeichers zuweisen. Entgegen der landläufigen Meinung (siehe den Ratschlag zu fast allen Fragen zum Puffer-Cache) erfolgt die automatische Freigabe des Speichers durch Löschen sauberer Cache-Einträge nicht sofort: Das Starten meiner Anwendung kann bis zu einer Minute dauern, wenn der Puffer-Cache voll ist ( *), während nach dem Löschen des Cache (mit echo 3 > /proc/sys/vm/drop_caches) die gleiche Anwendung fast sofort gestartet wird.

(*) Während dieser Minute der Startzeit ist die Anwendung fehlerhaft im neuen Speicher, verbringt jedoch 100% ihrer Zeit im Kernel, so Vtune in einer aufgerufenen Funktion pageblock_pfn_to_page. Diese Funktion scheint mit der Speicherkomprimierung zu tun zu haben, die zum Auffinden großer Seiten erforderlich ist, was mich zu der Annahme veranlasst, dass tatsächlich die Fragmentierung das Problem ist.

Wim
quelle
1
Es gibt so etwas wie Cache-Tiering. ceph osd pool set {cachepool} hit_set_count 1 ceph osd pool set {cachepool} hit_set_period 3600 ceph osd pool set {cachepool} target_max_bytes 1000000000000 als beispiel siehe. docs.ceph.com/docs/master/rados/operations/cache-tiering
Michael D.
2
Da dieses Problem anscheinend nur den Start der speicherintensiven Anwendungen betrifft, können Sie Apps möglicherweise über ein Skript starten, das den Cache löscht, bevor Sie sie tatsächlich starten. Vielleicht startet dies sie schneller, während die Cache-Verwaltung dem Kernel überlassen bleibt, während sie ausgeführt werden.
Thawn

Antworten:

14

Wenn Sie kein absolutes Limit wollen, sondern nur den Kernel unter Druck setzen, um die Puffer schneller zu leeren, sollten Sie nachsehen vm.vfs_cache_pressure

Diese Variable steuert die Tendenz des Kernels, den für das Caching von VFS-Caches verwendeten Speicher im Vergleich zu Pagecache und Swap zurückzugewinnen. Durch Erhöhen dieses Werts wird die Rate erhöht, mit der VFS-Caches zurückgefordert werden.

Der Bereich reicht von 0 bis 200. Bewegen Sie ihn für höheren Druck in Richtung 200. Die Standardeinstellung ist 100. Sie können die Speichernutzung auch mit dem slabtopBefehl analysieren . In Ihrem Fall die dentryund *_inode_cachemüssen Werte hoch sein.

Wenn Sie ein absolutes Limit wünschen, sollten Sie nachschlagen cgroups. Platzieren Sie den Ceph OSD-Server in einer cgroup und begrenzen Sie den maximal verfügbaren Speicher, indem Sie den memory.limit_in_bytesParameter für die cgroup festlegen.

memory.memsw.limit_in_bytesLegt den maximalen Betrag für die Summe der Speicher- und Auslagerungsnutzung fest. Wenn keine Einheiten angegeben sind, wird der Wert als Byte interpretiert. Es ist jedoch möglich, Suffixe zu verwenden, um größere Einheiten darzustellen - k oder K für Kilobyte, m oder M für Megabyte und g oder G für Gigabyte.

Verweise:

[1] - GlusterFS Linux Kernel Tuning

[2] - RHEL 6 Resource Management Guide

NOLFXceptMe
quelle
1
Eine cgroup mit limit_in_bytesset scheint es zu tun. Vielen Dank!
Wim
4
Ich denke vfs_cache_pressure, löscht nur Dentry- und Inode-Caches und hat nichts mit Buffer-Cache zu tun.
Kawing-Chiu
Eine Erhöhung vfs_cache_pressuredarüber 100kann hilfreich sein, falls Sie nicht über genügend RAM für Ihre Arbeitslast verfügen. Dies verringert die RAM-Auslastung, führt jedoch zu einer insgesamt schlechteren E / A-Leistung.
Mikko Rantalainen
3

Ich weiß nichts über A%, aber Sie können ein Zeitlimit festlegen, damit es nach x Minuten abfällt.

Zuerst in einem Terminal

sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

Aktuelle Caches löschen.

Machen Sie es zu einem cron-job Drücken Sie Alt-F2, geben Sie ein gksudo gedit /etc/crontabund fügen Sie diese Zeile unten hinzu.

 */15 *    * * *   root    sync && echo 3 > /proc/sys/vm/drop_caches

Dies reinigt alle 15 Minuten. Sie können 1 oder 5 Minuten einstellen, wenn Sie wirklich möchten, indem Sie den ersten Parameter auf * oder * / 5 anstelle von * / 15 ändern

So sehen Sie Ihren freien Arbeitsspeicher mit Ausnahme des Caches:

free -m | sed -n -e '3p' | grep -Po "\d+$
DnrDevil
quelle
Ich fühle hier ein bisschen Redundanz. Soweit ich weiß, 3 > drop_cachesbeinhaltet das das Verhalten vonsync
andras.tim
1
@ andras.tim no - sync schreibt fehlerhafte Seiten auf die Festplatte, 3 to drop_caches gibt nur Speicher frei, der von leeren Seiten und anderen Caches verwendet wird. Sie müssen die Synchronisierung nicht ausführen, aber wenn Sie dies tun, wird mehr Speicher sauber anstatt schmutzig und mehr Speicher wird freigegeben, wenn Sie Caches löschen
Daniel S. Sterling
2

Ich denke, Ihre Vermutung am Ende Ihrer Frage ist auf dem richtigen Weg. Ich würde annehmen, dass entweder A, NUMA-fähige Speicherzuordnung, Seiten zwischen CPUs migriert, oder B, eher der Defragmentierungscode transparenter riesiger Seiten, die versuchen, zusammenhängende, ausgerichtete Bereiche zu finden.

Riesenseiten und transparente Riesenseiten wurden sowohl für deutliche Leistungsverbesserungen bei bestimmten Workloads als auch für den Verbrauch enormer CPU-Zeit ohne großen Nutzen identifiziert.

Es wäre hilfreich zu wissen, welchen Kernel Sie ausführen, welchen Inhalt / proc / meminfo (oder zumindest die Werte für HugePages_ *) und, falls möglich, mehr von dem vtune profiler-Aufrufgraphen, der auf pageblock_pfn_to_page () verweist.

Wenn Sie sich meiner Vermutung hingeben möchten, deaktivieren Sie die Defragmentierung von Riesen-Seiten mit:

echo 'never'> / sys / kernel / mm / transparent_hugepage / defrag

(Es kann sein, dass dies stattdessen von Ihrem Kernel abhängt :)

echo 'never'> / sys / kernel / mm / redhat_transparent_hugepage / defrag

Und zu guter Letzt, verwendet diese App viele Dutzend Gigs RAM, die Sie geschrieben haben? Welche Sprache?

Da Sie den Begriff "Fehler in den Speicherseiten" verwendet haben, sind Sie wahrscheinlich mit dem Betriebsdesign und dem virtuellen Speicher vertraut. Ich habe Mühe, mir eine Situation / Anwendung vorzustellen, die so aggressiv fehlerhaft ist, dass nicht viele E / A eingelesen werden - fast immer aus dem Puffer-Cache, den Sie einschränken möchten.

(Wenn Sie neugierig sind, sehen Sie sich die mmap (2) -Flaggen wie MAP_ANONYMOUS und MAP_POPULATE und mincore (2) an, mit denen Sie feststellen können, auf welchen virtuellen Seiten tatsächlich eine physische Seite abgebildet ist.)

Viel Glück!

Ätherfisch
quelle
2

Wenn es sich bei Ceph OSD um einen separaten Prozess handelt, können Sie mithilfe von cgroups die vom Prozess verwendeten Ressourcen steuern:

Erstellen Sie eine cgroup mit dem Namen group1 mit einem Speicherlimit von 50 GB (z. B. werden andere Limits wie z. B. CPU unterstützt, in Beispiel wird auch CPU erwähnt):

cgcreate -g memory,cpu:group1

cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1

Wenn Ihre App bereits ausgeführt wird, bringen Sie sie in diese Gruppe:

cgclassify -g memory,cpu:group1 $(pidof your_app_name)

Oder führen Sie Ihre App in dieser Gruppe aus:

cgexec -g memory,cpu:group1 your_app_name
Alexei Martianov
quelle
0

tuned ist ein dynamischer adaptiver System-Tuning-Daemon, der die Systemeinstellungen je nach Verwendung dynamisch abstimmt.

 $ man tuned

Weitere Informationen finden Sie in der zugehörigen Dokumentation und in den Konfigurationsdateien.

 /etc/tuned
 /etc/tuned/*.conf
 /usr/share/doc/tuned-2.4.1
 /usr/share/doc/tuned-2.4.1/TIPS.txt

This parameter may be useful for you.

** Set flushing to once per 5 minutes
** echo "3000" > /proc/sys/vm/dirty_writeback_centisecs

Zusätzliche Information

Der Befehl sync leert den Puffer, dh erzwingt, dass alle ungeschriebenen Daten auf die Festplatte geschrieben werden, und kann verwendet werden, wenn sichergestellt werden soll, dass alles sicher geschrieben ist. In herkömmlichen UNIX-Systemen wird ein Programm namens update im Hintergrund ausgeführt, das alle 30 Sekunden eine Synchronisierung durchführt. Daher ist es normalerweise nicht erforderlich, die Synchronisierung zu verwenden. Linux hat einen zusätzlichen Daemon, bdflush , der häufiger eine unvollständigere Synchronisation durchführt, um ein plötzliches Einfrieren aufgrund von Festplatten-E / A zu vermeiden, die manchmal durch die Synchronisation verursacht werden.

Unter Linux wird bdflush per Update gestartet. Es gibt normalerweise keinen Grund, sich darüber Sorgen zu machen, aber wenn bdflush aus irgendeinem Grund abstürzt, warnt der Kernel davor und Sie sollten es manuell starten ( / sbin / update ).

Ijaz Ahmad Khan
quelle
1
Gilt das nicht nur für Dirty-Einträge? Ich denke nicht, dass dies das Problem auf meinem System ist, da sie alle sauber sind - die Verzögerung besteht nicht darin, schmutzige Seiten zurückzuschreiben, sondern den durch das Entfernen sauberer Seiten verbleibenden Speicherplatz zu defragmentieren.
Wim
Ja, dies gilt für schmutzige Seiten. Ich denke, Sie können auch andere Leistungsprobleme beheben, indem Sie den dynamischen Modus aktivieren.
Ijaz Ahmad Khan
"Seit Linux 2.6 ist der Systemaufruf [the bdflush] veraltet und macht nichts mehr. Er wird wahrscheinlich in einem zukünftigen Kernel-Release ganz verschwinden. Heutzutage wird die von bdflush () ausgeführte Aufgabe vom Kernel-Thread pdflush übernommen." man7.org/linux/man-pages/man2/bdflush.2.html
sourcejedi