linux中的内存是以page为单位进行管理的,
Page Cache是Linux内核中的一种缓存机制,用于缓存文件系统中的数据和元数据。
当应用程序读取文件时,文件的内容会被缓存到Page Cache中,如果下次再次读取该文件,内核会直接从Page Cache中读取数据,而不必再次访问磁盘。
page cache是存储在内存中的Page的一种特殊用法。
那page cache是如何产生的?又是如何释放的?pagecache和磁盘又有什么联系呢?
一、page cache是如何产生的
先看看drop cache里放的是什么:
https://www.kernel.org/doc/Documentation/sysctl/vm.txt
drop_caches
Writing to this will cause the kernel to drop clean caches, as well as
reclaimable slab objects like dentries and inodes. Once dropped, their
memory becomes free.
To free pagecache:
echo 1 > /proc/sys/vm/drop_caches
To free reclaimable slab objects (includes dentries and inodes):
echo 2 > /proc/sys/vm/drop_caches
To free slab objects and pagecache:
echo 3 > /proc/sys/vm/drop_caches
1.读写文件的内容
2.目录缓存
3.文件的元信息
上图中的:read,write,open,stat,chmod和这些可以关联起来,那我们来试验一下
1.1 写文件
root@new-ubuntu-server:~# echo 3 > /proc/sys/vm/drop_caches
root@new-ubuntu-server:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 131005584 10884 164044 0 0 0 0 6 4 0 0 100 0 0
0 0 0 131005584 10884 164044 0 0 0 0 6 4 0 0 100 0 0
关于vmstat,指标的含义我们在内存分析工具里面会详细介绍,这里我们关注
内存部分的 buff 和 cache ,以及 io 部分的 bi 和 bo 即可。
bi 和 bo 则分别表示块设备读取和写入的大小,单位为块 / 秒。因为 Linux 中块的大小是 1KB,所以这个单位也就等价于 KB/s。
这里简单提一下关于磁盘块大小https://wiki.linuxquestions.org/wiki/Block_devices_and_block_sizes
现在link block大小都是1KB,但如果文件系统设置的block size 是4096,那么即使一个很小的文件也要占文件系统4KB大小。
root@new-ubuntu-server:~# stat -f /home/
File: "/home/"
ID: c09974c1a4262947 Namelen: 255 Type: ext2/ext3
Block size: 4096 Fundamental block size: 4096
Blocks: Total: 25656558 Free: 24123371 Available: 22808555
Inodes: Total: 6553600 Free: 6463192
root@new-ubuntu-server:~# # df .
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sdb2 307599572 274077896 17896456 94% /mnt/sdb2
root@new-ubuntu-server:~# # echo hallo>welt
root@new-ubuntu-server:~# # df .
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sdb2 307599572 274077900 17896452 94% /mnt/sdb2
root@new-ubuntu-server:~# # du -csh welt
4.0K welt
4.0K total
正常情况下,空闲系统中,你应该看到的是,这几个值在多次结果中一直保持不变。接下来,
到第二个终端执行 dd 命令,通过读取随机设备,生成一个 500MB 大小的文件
root@new-ubuntu-server:~# dd if=/dev/urandom of=/tmp/file bs=1M count=500
root@new-ubuntu-server:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 131029536 3312 147252 0 0 0 0 6021 74 0 0 100 0 0
1 0 0 131022984 3320 153460 0 0 68 60 6044 119 0 0 100 0 0
1 0 0 130789888 3320 386232 0 0 0 0 6029 141 0 4 96 0 0
1 0 0 130555536 3320 619988 0 0 0 0 6020 100 0 4 96 0 0
0 1 0 130503888 3336 671876 0 0 16 512000 12914 8629 0 2 96 3 0
0 0 0 130503632 3336 672308 0 0 0 0 6071 140 0 0 100 0 0
0 0 0 130503632 3336 672308 0 0 0 0 6021 72 0 0 100 0 0
0 0 0 130503632 3348 672308 0 0 0 72 6034 92 0 0 100 0 0
0 0 0 130503632 3348 672308 0 0 0 0 6054 125 0 0 100 0 0
0 0 0 130503632 3348 672308 0 0 0 0 6018 68 0 0 100 0 0
通过观察 vmstat 的输出,我们发现,在 dd 命令运行时, Cache 在不停地增长,而 Buffer 基本保持不变。
最后bo输出512000也就是500MB的写入。
1.2 读文件
# 首先清理缓存
root@new-ubuntu-server:~# echo 3 > /proc/sys/vm/drop_caches
# 运行dd命令读取文件数据
root@new-ubuntu-server:~# dd if=/tmp/file of=/dev/null
root@new-ubuntu-server:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 1 0 7724164 2380 110844 0 0 16576 0 62 360 2 2 76 21 0
0 1 0 7691544 2380 143472 0 0 32640 0 46 439 1 3 50 46 0
0 1 0 7658736 2380 176204 0 0 32640 0 54 407 1 4 50 46 0
0 1 0 7626052 2380 208908 0 0 32640 40 44 422 2 2 50 46 0
观察 vmstat 的输出,你会发现读取文件时(也就是 bi 大于 0 时),Buffer 保持不变,而 Cache 则在不停增长。
经过这个案例说明文件的读写都要经过cache。
1.3 写磁盘
vmstat看到除了cache,还有个buffer,那buffer又是什么?
我们通过这个图可以看到buffer是在文件系统和磁盘设备之间,其实就是裸IO的缓存,他的作用就是读写的请求不经过文件系统,而是直接去读写裸设备的数据。我们也来试验一下就知道了:
我们往/dev/sda2这个磁盘写入2G数据(之前是写入/tmp/file这个是通过vfs写文件系统的)
#注意这个命令会将磁盘清空,所以要在空的数据盘做测试!!!!
root@new-ubuntu-server:/home# dd if=/dev/urandom of=/dev/sda2 bs=1M count=2048
2048+0 records in
2048+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 8.44153 s, 254 MB/s
root@new-ubuntu-server:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 128952928 5212