Mögliche Methode # 1 - F_DROP_CACHES
Ich habe eine Methode aus dem Jahr 2012 gefunden, die einen vorgeschlagenen Patch für den Linux-Kernel in diesem E-Mail-Thread mit dem Titel: Re: [RFC-Patch] fs: Implementiere Drop-Caches pro Datei .
Auszug
Cong> Dies ist ein Entwurfspatch zum Implementieren von Drop-Caches pro Datei.
Interessant. Kann ich das also außerhalb eines Prozesses tun? Ich bin ein SysAdmin. Mein POV besteht also darin, Leistungsprobleme zu bemerken, zu finden und zu beheben, wenn das System unter Druck steht.
Cong> It introduces a new fcntl command F_DROP_CACHES to drop
Cong> file caches of a specific file. The reason is that currently
Cong> we only have a system-wide drop caches interface, it could
Cong> cause system-wide performance down if we drop all page caches
Cong> when we actually want to drop the caches of some huge file.
Wie kann ich feststellen, wie viel Cache von einer Datei verwendet wird? Und wie wirkt sich dies auf die Leistung aus, wenn das System ausgelastet ist? Und was bringt uns dieser Patch, da ich der Meinung bin, dass die VM bereits Caches löschen sollte, wenn das System unter Mem-Druck gerät ...
Cong> Unten ist ein kleiner Testfall für diesen Patch:
Der Faden umfasst sowohl einen Testfall und die aktuelle Patch auf mehrere Dateien innerhalb des Linux - Kernels, die eine zusätzliche Funktion fügt fs/drop_caches.c
genannt drop_pagecache_file(struct file *filp)
. Diese Funktion ist dann über das Frontend-Tool fnctl.c
über den Befehl zugänglich F_DROP_CACHES
. Dieser Fall ruft diese Funktion auf:
file_drop_caches(filp, arg);
Welches behandelt das Löschen aller Caches, die mit der angegebenen Datei verbunden sind. Aus der Datei include/linux/mm.h
:
void file_drop_caches(struct file *filp, unsigned long which);
Das kann also genutzt werden?
Ich habe keine Hinweise darauf gefunden, dass dieser Patch jemals in das Haupt-Kernel-Code-Repository von Linux gelangt ist. Daher scheint diese Option nur verfügbar zu sein, wenn Sie bereit sind, den Linux-Kernel selbst neu zu kompilieren.
Mögliche Methode 2 - Verwenden von dd
In demselben Thread erwähnt ein anderer Benutzer eine völlig andere Methodik, die verwendet wird dd
.
Das Folgende ist ein Auszug aus dieser E-Mail
Dies ist eine nützliche Funktion. Obwohl es nicht bereits mit versehen ist
POSIX_FADV_DONTNEED
? Diese Funktionalität wurde vor einem Jahr zu GNU dd (8.11) hinzugefügt .
Hier sind die Beispiele aus diesem Patch:
Raten Sie, den Cache für die gesamte Datei zu löschen
$ dd if=ifile iflag=nocache count=0
Stellen Sie sicher, dass der Cache für die gesamte Datei gelöscht wird
$ dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
Cache für einen Teil der Datei löschen
$ dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
Streamen Sie Daten nur mit dem Read-Ahead-Cache
$ dd if=ifile of=ofile iflag=nocache oflag=nocache
Testen Sie es aus
Ich war nicht zu 100% sicher, wie ich das testen sollte, aber ich kam auf den folgenden Ansatz.
Erstellen Sie eine 100-MB-Datei
$ dd if=/dev/urandom of=sample.txt bs=100M count=1
Trace-Dateizugriffe mit fatrace
$ sudo fatrace | grep sample.txt
Laufen Sie, top
damit wir die Speichernutzung überwachen können.
$ top
Datei öffnen, Speicherplatz jetzt merken. Beachten Sie die fatrace
der Datei sample.txt
.
$ cat sample.txt > /dev/null
Löschen Sie die Datei aus dem Speicher und notieren Sie sich den freien Speicherplatz. Beachten Sie die Ausgabe von fatrace
.
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
Beispiel
Im Terminal 1:
$ dd if=/dev/urandom of=sample.txt bs=100M count=1
1+0 records in
1+0 records out
104857600 bytes (105 MB) copied, 7.37996 s, 14.2 MB/s
$ ls -l sample.txt
-rw-rw-r--. 1 saml saml 104857600 Oct 17 22:54 sample.txt
Im Terminal 2:
$ top
...
KiB Mem: 7968336 total, 6900956 used, 1067380 free, 267080 buffers
...
Im Terminal 3:
$ sudo fatrace | grep sample.txt
Öffnen Sie nun die Datei sample.txt
und notieren Sie die Größe des Arbeitsspeichers. Im Terminal Nr. 1.
$ cat sample.txt > /dev/null
Im Terminal 2:
KiB Mem: 7968336 total, 7011896 used, 956440 free, 267336 buffers
Beachten Sie die Ausgabe von fatrace
in Terminal 3:
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): R /home/saml/tst/162600/sample.txt
cat(25940): RC /home/saml/tst/162600/sample.txt
Entfernen Sie nun die Datei aus dem RAM in Terminal 4:
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
Beachten Sie die Ausgabe von fatrace
in Terminal # 2:
dd(26229): O /home/saml/tst/162600/sample.txt
dd(26229): CW /home/saml/tst/162600/sample.txt
Beachten Sie den RAM in Terminal 3:
KiB Mem: 7968336 total, 6908364 used, 1059972 free, 267364 buffers
Es scheint also, dass alles, was von der Datei im RAM verbraucht wurde, freigegeben wird.
Mögliche Methode # 3 - Python-Fadvise
Dank eines Kommentars von @frostchutz gibt es ein anderes Tool, ein Python-Skript mit dem Namen [pyadvise][4]
, das eine viel einfachere Oberfläche als die oben genannten dd
Methoden bietet . Dieses Skript verwendet dieselbe posix_fadvise(2)
Schnittstelle.
Beispiel
$ sudo pyadvise --help
Usage:
pyadvise [options] [FILE]..
Options:
-h, --help show this help message and exit
-w, --willneed The specified files will be accessed in the near future
-s, --sequential The application expects to access the specified files
sequentially (with lower offsets read before higher ones)
-d, --dontneed The specified files will not be accessed in the near
future
-r, --random The specified files will be accessed in random order
-o, --noreuse The specified files will be accessed only once. Under
Linux, this operation is a no-op; see contrib/copyfileobj-
fadvise.py in the python-fadvise source tree for an
example on how to achieve approximately the same effect
-n, --normal Indicates that the application has no advice to give about
its access pattern for the specified files. If no advice
is given for an open file, this is the default assumption
-v, --verbose Explain what is being done
Und wenn wir den obigen Test wiederholen und pyadvise
anstelle von dd
:
$ pyadvise -d /home/saml/tst/162600/sample.txt
Ich bemerkte einen identischen Abfall des RAM, der wie vorher verbraucht wurde, als ich benutzte dd
.