是否可以列出缓存的文件?


29

这里的输出free -m

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

我可以看到几乎6GB(5945MB)的内存7GB已用于缓存文件。我知道如何刷新缓存。我的问题是:是否可以查看正在缓存哪些文件(或inode)?


我不知道答案,但是有两件事很有趣:如何刷新缓存?为什么会对此感兴趣,我在这里并不表示任何含义-只是对用例感兴趣
serverhorror

2
这将同时冲洗bufferscachedsysctl -w vm.drop_caches=3。在使用之前,您可能需要阅读更多内容。有时只是需要。其可用-这应该是另一个原因:)
ssapkota 2011年

很多人都在要求它。应该有一些原因。
ssapkota 2011年

如果您想进行一些与I / O相关的性能测量,而又不想让它们被O / S缓存“破坏”,
那么丢弃

Answers:


25

嗯,一个简单的方法,如果你碰巧要看看内核的页面缓存ftools - “fincore”为您提供了哪些文件页面的缓存内容的一些概要信息。

您将需要提供文件名列表,以检查它们在页面缓存中的存在。这是因为存储在内核页面缓存表中的信息将仅包含数据块引用,而不包含文件名。fincore将通过索引节点数据解析给定文件的数据块,并在页面缓存表中搜索相应的条目。

没有有效的搜索机制来进行反向操作-获取属于数据块的文件名将需要读取文件系统上的所有inode和间接块。如果您需要了解存储在页面缓存中的每个文件的块,则需要提供文件系统上所有文件的列表到fincore。但这又可能破坏测量,因为将遍历目录读取大量数据,并获取所有inode和间接块-将它们放入页缓存中,并逐出要尝试检查的页缓存数据。


fincore会通知文件缓存中是否存在文件。但是,有没有什么工具可以列出所有已缓存的文件(fincore将文件名作为输入并进行搜索。我想查看当前已缓存的所有条目)
Joe

@Joe我想,存储在内核页面缓存表中的信息将仅包含数据块引用,而不包含文件名。fincore将通过索引节点数据解析给定文件的数据块,并在页面缓存表中搜索相应的条目。没有有效的搜索机制进行反向操作-获取属于数据块的文件名将需要读取文件系统上的所有inode和间接块。因此,从算法上讲,fincore如果确实需要此级别的信息,则最好提供文件系统上所有文件的列表。
the-wabbit 2014年

@ the-wabbit谢谢。除了文件外,还有其他的东西,是缓存的一部分,如描述符,共享内存等等

@Joe不幸的是,我对内核的内部了解还不足以给出有关该主题的权威性答案。页面缓存似乎足够通用,可以缓存其他类型的数据,而不仅仅是文件系统数据块,但是我不知道任何示例。
the-wabbit

1
StackExchange 关于过时答案的处理立场有些含糊。删除或实质性更改已接受的答案是不受欢迎的。更改此答案以推荐vmtouch将复制@ewwhite的现有答案,其支持率类似。因此,只要进一步提高ewwhite的答案就可以解决问题,对吗?
沃比特人

19

您可以使用vmtouch实用程序查看命名文件或目录是否在高速缓存中。您还可以使用该工具将项目强制放入缓存或将其锁定到缓存。

[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

现在,我可以将其“触摸”到缓存中。

[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

现在来看缓存了多少...

[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

3

我编写了一个非常简单的shell脚本,以使用linux-fincore显示缓存的文件。由于缓存是内存的一部分,因此我的代码将查找进程的前10个RSZ用法,并使用lsof找出进程打开的文件,最后使用linux-fincore来确定这些文件是否被缓存。

如果我认为错了,请纠正我。

#!/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}

1
缓存中的文件集通常会比当前打开的文件的小子集大得多(除非缓存空间很小)。当前打开的文件最有可能出现在缓存中(除非那些文件是长空闲或最近被清除的缓存)。注意:lsof还报告映射到进程地址空间(不一定缓存)中的文件。也很可能将仅部分/稀疏地缓存大量文件...
Vlad


2

我编写了以下脚本,该脚本使用pcstat命令打印所有文件及其缓存状态。它是x86_64 linux系统的自包含脚本。如果需要,它将下载pcstat。

第一个参数是要分析的文件系统位置,第二个参数是结果数(前N个按高速缓存中的页数)。

#!/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}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.