Est-il possible de lister les fichiers mis en cache?

29

Voici la sortie de free -m:

             total       used       free     shared    buffers     cached
Mem:          7188       6894        294          0        249       5945
-/+ buffers/cache:        698       6489
Swap:            0          0          0

Je peux voir presque 6GB(5945 Mo) de mémoire 7GButilisée pour la mise en cache des fichiers. Je sais comment vider les caches. Ma question est: est-il possible de voir quels fichiers (ou inodes) sont mis en cache?

ssapkota
la source
Je ne connais pas la réponse mais 2 choses sont intéressantes: comment vider les caches? Pourquoi est-ce intéressant, je n'implique rien ici - je m'intéresse simplement au cas d'utilisation
serverhorror
2
Cette fois le débusque bufferset cached: sysctl -w vm.drop_caches=3. Vous voudrez peut-être en savoir plus à ce sujet avant de l'utiliser. Parfois, c'est juste nécessaire. Son disponible - cela devrait être une autre raison :)
ssapkota
Beaucoup de gens le demandent . Il devrait y avoir une raison.
ssapkota
la suppression des caches est pratique si vous souhaitez effectuer des mesures de performances liées aux E / S et que vous ne voulez pas les «gâcher» par la mise en cache O / S
the-wabbit

Réponses:

25

Eh bien, il existe un moyen facile de jeter un œil au cache des pages du noyau si vous avez des ftools - "fincore" vous donne quelques informations récapitulatives sur les pages des fichiers qui sont le contenu du cache.

Vous devrez fournir une liste de noms de fichiers pour vérifier leur présence dans le cache de pages. En effet, les informations stockées dans les tables de cache de pages du noyau uniquement contiendront des références de blocs de données et non des noms de fichiers. fincorerésoudrait les blocs de données d'un fichier donné par le biais de données d'inode et rechercherait les entrées respectives dans les tables de cache de pages.

Il n'y a pas de mécanisme de recherche efficace pour faire l'inverse - obtenir un nom de fichier appartenant à un bloc de données nécessiterait la lecture de tous les inodes et blocs indirects du système de fichiers. Si vous avez besoin de connaître les blocs de chaque fichier stockés dans le cache de pages, vous devez fournir une liste de tous les fichiers de votre ou vos systèmes de fichiers fincore. Mais cela risque également de gâcher la mesure, car une grande quantité de données serait lue en parcourant les répertoires et en obtenant tous les inodes et blocs indirects - en les mettant dans le cache de pages et en expulsant les données du cache de pages que vous essayez d'examiner.

le-wabbit
la source
fincore informe si un fichier est présent dans le cache ou non. Cependant, existe-t-il un outil qui répertoriera tous les fichiers qui sont mis en cache (fincore prend le nom de fichier en entrée et recherche. Je veux examiner toutes les entrées qui sont actuellement mises en cache)
Joe
@Joe Je suppose que seules les informations stockées dans les tables de cache de pages du noyau contiendront des références de blocs de données et non des noms de fichiers. fincorerésoudrait les blocs de données d'un fichier donné par le biais de données d'inode et rechercherait les entrées respectives dans les tables de cache de pages. Il n'y a pas de mécanisme de recherche efficace faisant l'inverse - obtenir un nom de fichier appartenant à un bloc de données nécessiterait la lecture de tous les inodes et blocs indirects du système de fichiers. Ainsi, algorithmiquement, vous feriez mieux de fournir une liste de tous les fichiers de votre système de fichiers fincoresi vous avez vraiment besoin de ce niveau d'informations.
le-wabbit du
@ the-wabbit Merci. À part les fichiers, y a-t-il d'autres éléments qui font partie du cache, tels que des descripteurs, de la mémoire partagée, etc.
Joe
@Joe Malheureusement, je ne suis pas très profondément dans les internes du noyau pour donner une réponse faisant autorité sur ce sujet. Le cache de pages semble suffisamment générique pour mettre en cache d'autres types de données que les blocs de données du système de fichiers, mais je ne connais aucun exemple.
le-wabbit
1
La position de StackExchange sur ce qu'il faut faire avec les réponses obsolètes est quelque peu ambiguë. La suppression ou la modification substantielle des réponses acceptées est désapprouvée. Changer cette réponse pour recommander vmtouch dupliquerait la réponse existante de @ ewwhite, qui a un nombre similaire de votes positifs. Donc, simplement en augmentant la réponse d'ewwhite, cela devrait faire l'affaire, non?
le-wabbit du
19

Vous pouvez utiliser l' utilitaire vmtouch pour voir si un fichier nommé ou un répertoire est dans le cache. Vous pouvez également utiliser l'outil pour forcer les éléments dans le cache ou les verrouiller dans le cache.

[root@xt ~]# vmtouch -v /usr/local/var/orca/procallator.cfg
/usr/local/var/orca/procallator.cfg
[     ] 0/5

           Files: 1
     Directories: 0
  Resident Pages: 0/5  0/20K  0%
         Elapsed: 0.000215 seconds

Maintenant, je peux le "toucher" dans le cache.

[root@xt ~]# vmtouch -vt /usr/local/var/orca/procallator.cfg
/usr/local/var/orca/procallator.cfg
[OOOOO] 5/5

           Files: 1
     Directories: 0
   Touched Pages: 5 (20K)
         Elapsed: 0.005313 seconds

Maintenant, pour voir combien est mis en cache ...

[root@xt ~]# vmtouch -v /usr/local/var/orca/procallator.cfg
/usr/local/var/orca/procallator.cfg
[OOOOO] 5/5

           Files: 1
     Directories: 0
  Resident Pages: 5/5  20K/20K  100%
         Elapsed: 0.000241 seconds
ewwhite
la source
3

J'écris un script shell très simple pour montrer les fichiers mis en cache en utilisant linux-fincore. Étant donné que le cache est une partie de la mémoire, mon code est de trouver le top 10 des utilisations RSZ du processus, et d'utiliser lsof pour trouver les fichiers ouverts par le processus, enfin utiliser linux-fincore pour savoir si ces fichiers sont mis en cache ou non.

Veuillez me corriger si je pense mal.

#!/bin/bash
#Author: Shanker
#Time: 2016/06/08

#set -e
#set -u
#you have to install linux-fincore
if [ ! -f /usr/local/bin/linux-fincore ]
then
    echo "You haven't installed linux-fincore yet"
    exit
fi

#find the top 10 processs' cache file
ps -e -o pid,rss|sort -nk2 -r|head -10 |awk '{print $1}'>/tmp/cache.pids
#find all the processs' cache file
#ps -e -o pid>/tmp/cache.pids

if [ -f /tmp/cache.files ]
then
    echo "the cache.files is exist, removing now "
    rm -f /tmp/cache.files
fi

while read line
do
    lsof -p $line 2>/dev/null|awk '{print $9}' >>/tmp/cache.files 
done</tmp/cache.pids


if [ -f /tmp/cache.fincore ]
then
    echo "the cache.fincore is exist, removing now"

    rm -f /tmp/cache.fincore
fi

for i in `cat /tmp/cache.files`
do

    if [ -f $i ]
    then

        echo $i >>/tmp/cache.fincore
    fi
done

linux-fincore -s  `cat /tmp/cache.fincore`

rm -f /tmp/cache.{pids,files,fincore}
Shanker Lee
la source
1
L'ensemble des fichiers dans le cache va généralement être bien plus volumineux que le petit sous-ensemble des fichiers actuellement ouverts (sauf si l'espace du cache est petit). Les fichiers actuellement ouverts sont très probablement présents dans le cache (sauf s'ils étaient inactifs depuis longtemps ou que le cache a été récemment nettoyé). Remarque: lsofsignale également les fichiers mappés dans l'espace adresse du processus (et pas nécessairement mis en cache). Il est également probable qu'une grande partie des fichiers ne sera que partiellement / clairsemée en cache ...
Vlad
2

J'ai écrit le script suivant qui imprime tous les fichiers et leur état de cache à l'aide de la commande pcstat. Il s'agit d'un script autonome pour les systèmes Linux x86_64. Il télécharge pcstat si nécessaire.

Le premier argument est l'emplacement du système de fichiers à analyser et le deuxième argument est le nombre de résultats (N premiers par nombre de pages dans le cache).

#!/bin/bash
#Exit if a variable is not set
set -o nounset
#Exit on first error
set -o errexit

if [ $# -eq 0 ]; then
echo "Usage: $0 <root-dir> [number-of-results]"
echo
echo "Example $0 /var 10"
echo "will show top 10 files in /var which are loaded in cache"
exit
fi

ROOT=$1
#Number of results to show
HOW_MANY=50
[ -n ${2-} ] && HOW_MANY=$2


SCRIPT_DIR="$( cd -P "$( dirname "$0" )" && pwd )"
if [ ! -x $SCRIPT_DIR/pcstat ]; then
(
cd $SCRIPT_DIR
rm -f pcstat
curl -L -o pcstat https://github.com/tobert/pcstat/raw/2014-05-02-01/pcstat.x86_64
chmod +x pcstat
)
fi

FIND="find ${ROOT} -not ( -path /proc -prune ) -not ( -path /sys -prune ) -type f -size +0c -print0"
$FIND |  xargs -0 ${SCRIPT_DIR}/pcstat -terse -nohdr | sort --field-separator=, -r -n -k 6 | head -n ${HOW_MANY}
Nadddy
la source