Potencjalna metoda nr 1 - F_DROP_CACHES
Znalazłem metodę z 2012 roku, która omawia proponowaną poprawkę do jądra Linuksa w tym wątku pocztowym zatytułowaną: Re: [Poprawka RFC] fs: zaimplementuj pamięci podręczne dla poszczególnych plików .
fragment
Cong> To jest robocza poprawka implementująca pamięci podręczne dla poszczególnych plików.
Ciekawy. Czy mogę to zrobić spoza procesu? Jestem SysAdminem, więc mój POV polega na zauważaniu, znajdowaniu i naprawianiu problemów z wydajnością, gdy system jest pod presją.
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.
Skąd mam wiedzieć, ile pamięci podręcznej zajmuje plik? A jaki to ma wpływ na wydajność, gdy jest uruchomiony w obciążonym systemie? Co kupuje nas ta łatka, ponieważ uważam, że VM powinna już zrzucać pamięci podręczne, gdy system znajdzie się pod presją pamięci ...
Cong> Poniżej znajduje się mały przypadek testowy dla tej poprawki:
Wątek zawiera zarówno walizkę testową, jak i aktualną poprawkę do kilku plików w jądrze Linuksa, co dodaje dodatkową funkcję do fs/drop_caches.c
wywołanej drop_pagecache_file(struct file *filp)
. Ta funkcja jest następnie dostępna za pomocą narzędzia interfejsu użytkownika, fnctl.c
za pomocą polecenia F_DROP_CACHES
. Ten przypadek wywołuje tę funkcję:
file_drop_caches(filp, arg);
Który obsługuje usuwanie wszystkich pamięci podręcznych powiązanych z danym plikiem. Z pliku include/linux/mm.h
:
void file_drop_caches(struct file *filp, unsigned long which);
Więc można to wykorzystać?
Nie znalazłem żadnych dowodów na to, że łatka ta kiedykolwiek trafiła do głównego repozytorium kodu jądra systemu Linux, więc ta opcja wydaje się być dostępna, tylko jeśli sam zechcesz ponownie skompilować jądro systemu Linux.
Potencjalna metoda nr 2 - Korzystanie z dd
W tym samym wątku inny użytkownik wspomina o zupełnie innej metodologii, z której korzysta dd
.
Oto fragment tego e-maila
Jest to przydatna funkcjonalność. Chociaż nie jest jeszcze wyposażony
POSIX_FADV_DONTNEED
? Ta funkcjonalność została dodana do GNU dd (8.11) rok temu .
Oto przykłady z tej poprawki:
Zaleca się upuszczenie pamięci podręcznej dla całego pliku
$ dd if=ifile iflag=nocache count=0
Zapewnij pamięć podręczną dla całego pliku
$ dd of=ofile oflag=nocache conv=notrunc,fdatasync count=0
Upuść pamięć podręczną dla części pliku
$ dd if=ifile iflag=nocache skip=10 count=10 of=/dev/null
Przesyłaj strumieniowo dane, używając tylko pamięci podręcznej z wyprzedzeniem
$ dd if=ifile of=ofile iflag=nocache oflag=nocache
Testuję to
Nie byłem w 100% pozytywny, jak to sprawdzić, ale wpadłem na następujące podejście.
zrób plik 100 MB
$ dd if=/dev/urandom of=sample.txt bs=100M count=1
dostęp do pliku śledzenia za pomocą fatrace
$ sudo fatrace | grep sample.txt
uruchom top
, abyśmy mogli monitorować wykorzystanie pamięci, bez dodatkowych informacji.
$ top
otwórz plik, zanotuj teraz ilość wolnej pamięci. Zanotuj fatrace
plik sample.txt
.
$ cat sample.txt > /dev/null
upuść plik z pamięci, zauważ teraz ilość wolnej pamięci. Zwróć uwagę na wynik fatrace
.
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
Przykład
W terminalu 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
W terminalu 2:
$ top
...
KiB Mem: 7968336 total, 6900956 used, 1067380 free, 267080 buffers
...
W terminalu 3:
$ sudo fatrace | grep sample.txt
Teraz otwórz plik sample.txt
i zanotuj ilość pamięci RAM. W terminalu 1.
$ cat sample.txt > /dev/null
W terminalu 2:
KiB Mem: 7968336 total, 7011896 used, 956440 free, 267336 buffers
Zwróć uwagę na wynik fatrace
w terminalu 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
Teraz usuń plik z pamięci RAM w terminalu 4:
$ sudo dd of=/home/saml/tst/162600/sample.txt \
oflag=nocache conv=notrunc,fdatasync count=0
Zwróć uwagę na wynik fatrace
w terminalu 2:
dd(26229): O /home/saml/tst/162600/sample.txt
dd(26229): CW /home/saml/tst/162600/sample.txt
Zwróć uwagę na pamięć RAM w terminalu 3:
KiB Mem: 7968336 total, 6908364 used, 1059972 free, 267364 buffers
Wygląda więc na to, że wszystkie zużyte przez plik w pamięci RAM są zwolnione.
Potencjalna metoda # 3 - python-fadvise
Dzięki komentarzowi @frostchutz istnieje inne narzędzie, skrypt w języku Python, o nazwie, [pyadvise][4]
który zapewnia znacznie prostszy interfejs niż powyższe dd
metody. Ten skrypt korzysta z tego samego posix_fadvise(2)
interfejsu.
Przykład
$ 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
A jeśli powtórzymy powyższy test i użyjemy pyadvise
zamiast dd
:
$ pyadvise -d /home/saml/tst/162600/sample.txt
Zauważyłem identyczny spadek zużycia pamięci RAM, jak poprzednio, kiedy korzystałem dd
.