• Ukieweb

    佳的博客

    曾梦想仗剑天涯,后来工作忙没去。

linux 系统 内存中的 Buffer 和 Cache 解释

1. page cache 和 buffer cache 定义

Linux 2.4 及以后的内核版本中,page cache 和  Buffer Cache 的定义

什么是 page cache

Page Cache 包含 code 和 data,即 file’s IO block pages。实际上,我们所有的应用程序都驻留在 page cache pool。

当cpu访问 page 时候,new pages将立即更新到缓存中。下次访问时,CPU首先检查page cache,如果不可用再从磁盘访问。他从磁盘缓存数据,以加快后续I/O的速度。

什么是 Buffer Cache 

保留 buffer cache 是为了当内核仍需要执行 block I/O 操作时使用。块通常代表的是文件的数据。因此,大多数 buffer cache 都指向/链接到 page cache。但是,还是会有少量的 block data 需要保存在 buffer cache 而不是 page cache.

2. buffer cache 和 page cache 的区别

Linux 内核版本 2.4  之前  Page Cache 和 Buffer Cache 是不同的,从2.4内核开始,这两个缓存已合并。今天,只有一个缓存,即 Page Cache。但是在两者的理解上还是略有不同。怎么合并的看上面的定义。

  • page cache 存储 pages of files 以优化 file I/O 

  • buffer cache 存储 disk blocks 以优化 block I/O.

从内核版本2.4之前

Files' cache 存储在 page cache,,disk blocks 存储在 buffer cache。有时 disk blocks 通常引用相同的 file data,因此,数据在每个缓存中都存在,被引用两次

为了避免这种行为,Page & Buffer cache 在 2.4 内核版本中进行了修改。从内核版本2.4开始,page caches 和 buffer caches 合并了。

Virtual machine subsystem 现在通过在 page cache 中缓存 files' data 和 pages。如果缓存的数据同时包含 file 和 block,需要缓存在 buffer 时,buffer 仅将简单地指向/链接到页面缓存中的数据即可。

3. 写数据

如果需要写入数据,则首先将其写入 Page Cache 并作为其 dirty pages 之一进行管理。Dirty 意味着数据存储在 Page Cache ,而不是立马写入底层的存储设备。这些 dirty pages 的内容会定期(或者调用 sync 或 fsync 手动立马同步)写入底层的存储设备。

示例

下面的示例将显示一个10 MB的文件的创建过程,该文件将首先写入页面缓存中。这样做会增加脏页的数量,直到它们被写入基础固态驱动器(SSD)为止,在这种情况下,它们是根据sync命令手动写入的。

[root@localhost ~]# sync

[root@localhost ~]# cat /proc/meminfo | grep Dirty
Dirty:                 0 kB

[root@localhost ~]# dd if=/dev/zero of=laojia.txt bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.00733209 s, 1.4 GB/s

[root@localhost ~]# cat /proc/meminfo | grep Dirty                   
Dirty:             10240 kB

[root@localhost ~]# sync

[root@localhost ~]# cat /proc/meminfo | grep Dirty
Dirty:                 0 kB

pdflush 和 flush 

这两个线程是确保将脏页定期写入底层存储设备

  • 2.6.31- 之前是 pdfulsh 

  • 2.6.32+ 是 flush 

他们的不同是 flush 为每个底层存储设置启用一个线程,以提高性能。

root@pc:~# ls -l /dev/sda
brw-rw---- 1 root disk 8, 0 2011-09-01 10:36 /dev/sda
root@pc:~# ls -l /dev/sdb
brw-rw---- 1 root disk 8, 16 2011-09-01 10:36 /dev/sdb

root@pc:~# ps -eaf | grep -i flush
root       935     2  0 10:36 ?        00:00:00 [flush-8:0]
root       936     2  0 10:36 ?        00:00:00 [flush-8:16]
  • 现在:未找到flush线程。未知!

[root@localhost ~]# uname -r
3.10.0-957.1.3.el7.x86_64

[root@localhost ~]# ps -eaf |grep -v grep |grep -i flush
[root@localhost ~]#

4. 读数据

File blocks不仅在过程中会使用 Page Cache,而且在读取文件时也会写入Page Cache。

譬如当您两次读取一个100 MB的文件时,第二次访问会更快,因为文件块直接来自内存中的Page Cache,而不必再次从硬盘中读取。

示例:

我们读取一个 13M 的文件来看看 cache 的变化

[root@localhost ~]# ls -lh /tmp/file3.log  
-rw-r--r--. 1 root root 13M Jan 14 15:32 /tmp/file3.log

[root@localhost ~]# cat  /tmp/file3.log  

# 另外一个终端,查看 cache 的变化 80-67 = 13M 正好是 file3 的大小
[root@localhost ~]# free -m -s 1                      
              total        used        free      shared  buff/cache   available
Mem:            487          73         345          16          67         362
Swap:          2047           1        2046
              total        used        free      shared  buff/cache   available
Mem:            487          73         345          16          67         362
Swap:          2047           1        2046
              total        used        free      shared  buff/cache   available
Mem:            487          74         343          16          69         362
Swap:          2047           1        2046
              total        used        free      shared  buff/cache   available
Mem:            487          74         341          16          71         362
Swap:          2047           1        2046
              total        used        free      shared  buff/cache   available
Mem:            487          74         341          16          71         362
Swap:          2047           1        2046
              total        used        free      shared  buff/cache   available
Mem:            487          74         337          16          75         362
Swap:          2047           1        2046
              total        used        free      shared  buff/cache   available
Mem:            487          74         337          16          75         362
Swap:          2047           1        2046
              total        used        free      shared  buff/cache   available
Mem:            487          74         332          16          80         362
Swap:          2047           1        2046
              total        used        free      shared  buff/cache   available
Mem:            487          74         332          16          80         362
Swap:          2047           1        2046
              total        used        free      shared  buff/cache   available
Mem:            487          74         332          16          80         362
Swap:          2047           1        2046

5. Buffer 和 Cache 的 误解

两个疑问:

  • 第一个问题:Buffer 的文档没有提到这是磁盘读数据还是写数据的缓存,而在很多网络搜索的结果中都会提到 Buffer 只是对将要写入磁盘数据的缓存。那反过来说,它会不会也缓存从磁盘中读取的数据呢?

  • 第二个问题:文档中提到,Cache 是对从文件读取数据的缓存,那么它是不是也会缓存写文件的数据呢?

答案:

  • 简单来说,Buffer 是对磁盘数据的缓存,而 Cache 是文件数据的缓存,它们既会用在读请求中,也会用在写请求中。

6. 扩展:proc 文件系统对 buffers 和 cached 的解释

/proc 是 Linux 内核提供的一种特殊文件系统,是用户跟内核交互的接口。用户可以从 /proc 中查询内核的运行状态配置选项,查询进程的运行状态统计数据等,当然,你也可以通过 /proc 来修改内核的配置

proc文件系统同时也是很多性能工具的数据来源,比如我们刚看到的free,就是通过读取/proc/meminfo ,得到内存的使用情况。在 /proc/meminfo,有字段 Buffers、Cached、SReclaimable 这几个字段。执行 man proc ,你就可以得到详细文档

Buffers %lu
Relatively temporary storage for raw disk blocks that shouldn't get tremendously large (20MB or so).
 
Cached %lu
In-memory cache for files read from the disk (the page cache). Doesn't include SwapCached.
...
SReclaimable %lu (since Linux 2.6.19)
Part of Slab, that might be reclaimed, such as caches.
 
SUnreclaim %lu (since Linux 2.6.19)
Part of Slab, that cannot be reclaimed on memory pressure.
  • Buffers 是对原始磁盘块临时存储,也就是用来缓存磁盘的数据,通常不会特别大(20MB左右),这样,内核就可以把分散的写集中起来统一优化磁盘的写入,比如可以把多次小的写合并成单词大的写等等

  • Cached 是从磁盘读取文件的页缓存,也就是用来缓存从文件读取的数据。这样,下次访问这些文件数据时,就可以直接从内存中快速获取,而不需要再次访问缓慢的磁盘。

  • SReclaimableSlab 的一部分。Slab包括两部分,其中的可回收部分,用 SReclaimable 记录;而不可回收部分,用 SUnreclaim 记录。


参考:

Difference between buffer and page cache in Linux ?

Linux Page Cache Basics

kernel 官网 page cache 的说明


0
0
下一篇:linux 内存中 page cached 等 缓存 的查看 使用和释放

0 条评论

老佳啊

85后,大专学历,中原人士,家里没矿。

由于年轻时长的比较帅气,导致在别人眼里,我一直不谈恋爱的原因是清高,实则是自己的小自卑。最大的人生目标就是找一个相知相爱相容的人,共度余生。

和人相处时如果能感受到真诚,会非常注重彼此的关系,对别人没有什么心机,即使有利益冲突,一般也会以和为贵,因为在这个世界上,物质的东西,从来不会吸引到我。

特别迷恋那些大山大水,如果现在还能隐居,可能早就去了。对那些宏伟的有底蕴的人文景观比较不感冒。

从事于IT行业,却一直对厨房念念不忘,由于身材魁梧,总觉得自己上辈子是个将军,可惜这辈子没当兵,也不会打架。