É possível listar os arquivos armazenados em cache?

29

Aqui a saída de free -m:

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

Consigo ver quase 6GB(5945MB) de memória fora 7GBusada no cache dos arquivos. Eu sei como liberar os caches. Minha pergunta é: É possível ver quais arquivos (ou inodes) estão sendo armazenados em cache?

ssapkota
fonte
Não sei a resposta, mas duas coisas são de interesse: como você limpa os caches? Por que é que de interesse, eu não estou insinuando nada aqui - apenas interessados no caso de uso
serverhorror
2
Isso libera tanto o bufferse cached: sysctl -w vm.drop_caches=3. Você pode querer ler mais sobre isso antes de usar. Às vezes é apenas necessário. Seu disponível - isto deve ser outra razão :)
ssapkota
Muitas pessoas estão pedindo por isso . Deve haver algum motivo.
precisa saber é o seguinte
largando caches se torna útil se você quiser fazer alguma I / O relacionadas medições de desempenho e não quer tê-los "mimados" por O / S caching
o wabbit

Respostas:

25

Bem, não é uma maneira fácil de dar uma olhada em cache de página do kernel, se acontecer de você ter fTools - "fincore" dá-lhe algumas informações resumidas sobre as páginas dos ficheiros são o conteúdo do cache.

Você precisará fornecer uma lista de nomes de arquivos para verificar a presença deles no cache da página. Isso ocorre porque as informações armazenadas nas tabelas de cache da página do kernel conterão apenas referências de bloco de dados e não nomes de arquivos. fincoreresolveria os blocos de dados de um determinado arquivo através dos dados do inode e procuraria pelas entradas respectivas nas tabelas de cache da página.

Não há mecanismo de pesquisa eficiente para fazer o inverso - obter um nome de arquivo pertencente a um bloco de dados exigiria a leitura de todos os inodes e blocos indiretos no sistema de arquivos. Se você precisar conhecer os blocos de todos os arquivos armazenados no cache da página, precisará fornecer uma lista de todos os arquivos no (s) seu (s) sistema (s) de arquivos fincore. Mas isso provavelmente estragará a medição, pois uma grande quantidade de dados seria lida nos diretórios e obtendo todos os inodes e blocos indiretos - colocando-os no cache da página e expulsando os dados do cache da página que você estava tentando examinar.

o wabbit
fonte
O fincore informa se um arquivo está presente no cache ou não. No entanto, existe alguma ferramenta que irá listar todos os arquivos que são armazenados em cache (fincore leva o nome do arquivo como entrada e pesquisas Quero olhar para todas as entradas que estão atualmente em cache.)
Joe
@ Joe Suponho que as informações armazenadas nas tabelas de cache da página do kernel conterão apenas referências de bloco de dados e não nomes de arquivos. fincoreresolveria os blocos de dados de um determinado arquivo através dos dados do inode e procuraria pelas entradas respectivas nas tabelas de cache da página. Não há mecanismo de pesquisa eficiente fazendo o inverso - obter um nome de arquivo pertencente a um bloco de dados exigiria a leitura de todos os inodes e blocos indiretos no sistema de arquivos. Assim, algoritmicamente, será melhor fornecer uma lista de todos os arquivos em seu sistema de arquivos fincorese você realmente precisar desse nível de informação.
the-wabbit
@ the-wabbit Obrigado. Diferente de arquivos, há outras coisas que fazem parte do cache, como descritores, memória compartilhada etc.
Joe
@ Joe Infelizmente, eu não sou tão profundo no interior do Kernel para dar uma resposta autorizada sobre esse tópico. O cache da página parece genérico o suficiente para armazenar em cache outros tipos de dados além dos blocos de dados do sistema de arquivos, mas não conheço nenhum exemplo.
the-wabbit
1
A posição do StackExchange sobre o que fazer com respostas obsoletas é um tanto ambígua. Excluir ou alterar substancialmente as respostas aceitas é desaprovado. Alterar essa resposta para recomendar o vmtouch duplicaria a resposta existente do @ ewwhite, que possui um número semelhante de votos. Então, simplesmente dar mais apoio à resposta do ewwhite deve fazer o truque, certo?
the-wabbit
19

Você pode usar o utilitário vmtouch para verificar se um arquivo ou diretório nomeado está no cache. Você também pode usar a ferramenta para forçar itens ao cache ou bloqueá-los no 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

Agora eu posso "tocá-lo" no 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

Agora, para ver quanto é armazenado em 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
fonte
3

Eu escrevo um shell script muito simples para mostrar os arquivos em cache usando o linux-fincore. Como o cache é uma parte da memória, meu código encontra os 10 principais usos do processo RSZ e o lsof para descobrir os arquivos que foram abertos, finalmente use o linux-fincore para descobrir se esses arquivos estão em cache ou não.

Por favor, corrija-me se estiver errado.

#!/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
fonte
1
O conjunto de arquivos no cache normalmente será muito maior que o pequeno subconjunto dos arquivos atualmente abertos (a menos que o espaço do cache seja pequeno). Os arquivos atualmente abertos provavelmente estão presentes no cache (a menos que eles tenham sido inativos ou que o cache tenha sido limpo recentemente). Nota: lsoftambém relata arquivos mapeados no espaço de endereço do processo (e não necessariamente em cache). Também provável que grande parte dos arquivos vai ser apenas parcialmente / esparsamente em cache ...
Vlad
2

Você também pode usar o pcstat (Stat de cache da página) https://github.com/tobert/pcstat

Espero que ajude alguém.

blavoie
fonte
2

Eu escrevi o seguinte script que imprime todos os arquivos e seu status de cache usando o comando pcstat. É um script independente para sistemas linux x86_64. Faz o download do pcstat, se necessário.

O primeiro argumento é a localização do sistema de arquivos a ser analisada e o segundo argumento é o número do resultado (N superior pelo número de páginas no 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
fonte