[转帖]Linux Page cache和Buffer cache

linux,page,cache,buffer · 浏览次数 : 0

小编点评

## Page Cache与Buffer Cache简介 **Page Cache**是针对文件系统的缓存,它可以缓存文件的逻辑数据,包括文件指针、大小、时间等。**Buffer Cache**是针对磁盘块的缓存,它可以缓存磁盘块的实际数据,包括文件数据、块大小等。 **Page Cache与Buffer Cache的区别** * Page Cache是针对文件系统的缓存,它可以缓存文件的逻辑数据。 * Buffer Cache是针对磁盘块的缓存,它可以缓存磁盘块的实际数据。 **Page Cache的作用** * 缓存文件数据,提高读取效率。 * 减少对磁盘块的访问,提高性能。 **Buffer Cache的作用** * 缓存磁盘数据,提高写入效率。 * 减少频繁写磁盘的操作,提高性能。 **Page Cache与Buffer Cache的关系** * Page Cache包含了对Buffer Cache的描述符单元:buffer_head。 * 两个Cache之间通过buffer_head进行通信。 * 当页面被刷新时,Buffer Cache会从Page Cache中读取数据并写入磁盘。 **Page Cache与Buffer Cache的应用** * 文件系统中的缓存。 *磁盘块的缓存。 **Page Cache与Buffer Cache的优缺点** **Page Cache** * 缓存逻辑数据,提高读取效率。 * 减少对磁盘块的访问。 **Buffer Cache** * 缓存磁盘数据,提高写入效率。 * 减少频繁写磁盘的操作。 **Page Cache与Buffer Cache的联系** * Page Cache包含了对Buffer Cache的描述符单元:buffer_head。 * 两个Cache之间通过buffer_head进行通信。 * 当页面被刷新时,Buffer Cache会从Page Cache中读取数据并写入磁盘。

正文

https://www.cnblogs.com/hongdada/p/16926655.html

free 命令常用参数

free 命令用来查看内存使用状况,常用参数如下:

  • -h human-readable 格式打印
  • -w 把 cache & buffer 分开打印
  • -t show total for RAM + swap

free 结果指标剖析

centos6中,cache,buffers是分开的,7以后就合并了,cache/buffers

 
[root@10-23-220-95 ~]# free -hwt
              total        used        free      shared     buffers       cache   available
Mem:           7.6G        2.0G        3.3G        384M          0B        2.3G        4.9G
Swap:          511M        114M        397M
Total:         8.1G        2.1G        3.7G

Mem total 表示总计可用的物理内存大小

used 表示分配给进程的内存大小

free 未使用的内存大小

cache/buffers 是操作系统用来做缓存的内存占用,未被使用的内存不能白白浪费,操作系统会拿它用作缓存以此提升性能

total = used + free + cache/buffers。当 free 内存被用完后,cache/buffers 会释放一些供应用程序使用,所以 available (可用内存空间)要比 free 大一些。

Swap 是磁盘上划分出来供内存使用的空间,经常不用的东西没必要放在内存里,可以把它置换到外存中,需要的时候再加载的内存。

buffers/cache 进一步理解

当我们使用 free -th -w 查看主机内存信息的时候,常会发现 buffers/cache 占了许多内存空间。这些占用是用来做什么的呢?什么时候我需要扩内存了呢?

其实,buffers/cache 用掉的空间是用来做磁盘页缓存的,它使得系统运转更加快速。除了使得新手迷惑以外,没有其他任何弊端。buffers/cache 不会与应用程序争抢内存空间,只要应用程序需要等多的内存,它就把用来做磁盘页缓存的内存段归还回去,给到应用程序使用

什么时候开始真正小心内存不够用了?

  1. available memory 接近于 0
  2. swap used 增长或者波动
  3. dmesg | grep oom-killer 能够查看到 OutOfMemory-killer 在工作

shared memory 的理解

 
root@cloud:~ # free -t
              total        used        free      shared  buff/cache   available
Mem:      131106128     6740848   113822952     1376104    10542328   122002484
Swap:             0           0           0
Total:    131106128     6740848   113822952

通过 free 的输出可以看到,有一列 shared 项。free 命令的信息来源是 /proc/meminfo,shared 列的数据来自于 Shmem 部分。

 
root@cloud:~ # cat /proc/meminfo  | grep Shmem
Shmem:           1376104 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB

shared memory 统计的是被 tmpfs 所使用的内存大小。我们可以通过 df -t 来查看 tmpfs 所站的空间大小

 
root@cloud:~ # df -T | grep tmpfs
udev           devtmpfs   65538520        0   65538520   0% /dev
tmpfs          tmpfs      13110616  1375724   11734892  11% /run
tmpfs          tmpfs      65553064      340   65552724   1% /dev/shm
tmpfs          tmpfs          5120        0       5120   0% /run/lock
tmpfs          tmpfs      65553064        0   65553064   0% /sys/fs/cgroup
shm            tmpfs         65536        0      65536   0% /data/docker-data/containers/6c626b670a9f9f6fe05f65a29c3f4ea223814dc39ca5416547a1e405f64c715c/mounts/shm
shm            tmpfs         65536        0      65536   0% /data/docker-data/containers/2ca280f90cab45f8249a7c8b0959b7cf4f62da5ccf29c3f41148df4fe92362f2/mounts/shm
shm            tmpfs         65536        0      65536   0% /data/docker-data/containers/3a6ed95e443e72b2821bc68932e06f6cf18bb7bbf21b71f50bb59b405857e28c/mounts/shm
shm            tmpfs         65536        0      65536   0% /data/docker-data/containers/d4c079af0ac5ec2e5faaa476d46baba8971729f44e9090a383ce9b4d2032d69c/mounts/shm
tmpfs          tmpfs      13110612        0   13110612   0% /run/user/0

如果我们把 tmpfs Used 列数字加起来,会发现和 free 中 shared 基本相等(因为这个数据是动态一直在变化的)。那么什么是 tmpfs 呢?

tmpfs 是一个完全存在于内存里的文件系统,和其他内存数据一样,一切都是临时数据,重启机器后会丢失。tmpfs 的挂载和其他磁盘挂载类似,也可以在 /etc/fstab 内配置。

扇区sector

硬盘的读写以扇区为基本单位。磁盘上的每个磁道被等分为若干个弧段,这些弧段称之为扇区。硬盘的物理读写以扇区为基本单位。通常情况下每个扇区的大小是 512 字节。linux 下可以使用 fdisk -l 了解扇区大小:

 
$ sudo /sbin/fdisk -l
Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x7d9f5643

其中 Sector size,就是扇区大小,本例中为 512 bytes。

扇区是磁盘物理层面的概念,操作系统是不直接与扇区交互的,而是与多个连续扇区组成的磁盘块交互。由于扇区是物理层面的概念,所以无法在系统中进行大小的更改。

2009年后,硬盘厂商开始发布4KB字节扇区的硬盘了,4KB扇区硬盘已经在消费级市场广泛应用。但是同一块硬盘上的扇区大小一定是一致的

块/簇 IO Block

文件系统读写数据的最小单位,也叫磁盘簇。window系统叫簇,Linux叫块,是操作系统虚拟出来的逻辑概念,扇区是磁盘最小的物理存储单元,操作系统将相邻的扇区组合在一起,形成一个块,对块进行管理。每个磁盘块可以包括 2、4、8、16、32 或 64 个扇区。磁盘块是操作系统所使用的逻辑概念,而非磁盘的物理概念。磁盘块的大小可以通过命令 stat /boot 来查看:

 
$ sudo stat /boot
  File: /boot
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: 801h/2049d  Inode: 655361      Links: 3
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2019-07-06 20:19:45.487160301 +0800
Modify: 2019-07-06 20:19:44.835160301 +0800
Change: 2019-07-06 20:19:44.835160301 +0800
 Birth: -

其中 IO Block 就是磁盘块大小,本例中是 4096 Bytes,一般也是 4K。

为了更好地管理磁盘空间和更高效地从硬盘读取数据,操作系统规定一个磁盘块中只能放置一个文件,因此文件所占用的空间,只能是磁盘块的整数倍,那就意味着会出现文件的实际大小,会小于其所占用的磁盘空间的情况。

test2.txt是一个只包含一个字母的文本文档。它的理论大小是一个字节,但是由于系统的磁盘块大小是4KB(文件的最小存储大小单位),所以test2.txt占据的磁盘实际空间是4KB

操作系统不能对磁盘扇区直接寻址操写,主要原因是扇区数量庞大,因此才将多个连续扇区组合一起操作。磁盘块的大小是可以通过blockdev命令更改的。

页 page

内存的最小存储单位。页的大小通常为磁盘块大小的 2^n 倍,可以通过命令 getconf PAGE_SIZE 来获取页的大小:

 
$sudo getconf PAGE_SIZE
4096

本例中为 4096 Bytes,与磁盘块大小一致。

总结两个逻辑单位:

  • 页,内存操作的基本单位
  • 磁盘块,磁盘操作的基本单位

Page Cache

Page Cache以Page为单位,缓存文件内容。缓存在Page Cache中的文件数据,能够更快的被用户读取。同时对于带buffer的写入操作,数据在写入到Page Cache中即可立即返回,而不需等待数据被实际持久化到磁盘,进而提高了上层应用读写文件的整体性能。

Buffer Cache

磁盘的最小数据单位为sector,每次读写磁盘都是以sector为单位对磁盘进行操作。

sector大小跟具体的磁盘类型有关,有的为512Byte, 有的为4K Bytes。无论用户是希望读取1个byte,还是10个byte,最终访问磁盘时,都必须以sector为单位读取,如果裸读磁盘,那意味着数据读取的效率会非常低。

同样,如果用户希望向磁盘某个位置写入(更新)1个byte的数据,他也必须整个刷新一个sector,言下之意,则是在写入这1个byte之前,我们需要先将该1byte所在的磁盘sector数据全部读出来,在内存中,修改对应的这1个byte数据,然后再将整个修改后的sector数据,一口气写入磁盘。

为了降低这类低效访问,尽可能的提升磁盘访问性能,内核会在磁盘sector上构建一层缓存,他以sector的整数倍力度单位(block),缓存部分sector数据在内存中,当有数据读取请求时,他能够直接从内存中将对应数据读出。当有数据写入时,他可以直接再内存中直接更新指定部分的数据,然后再通过异步方式,把更新后的数据写回到对应磁盘的sector中。这层缓存则是块缓存Buffer Cache。

Page cache与Buffer Cache作用

page cache :页缓存,负责缓存逻辑数据。

buffer cache : 块缓存,负责缓存物理数据。

CacheBuffer是我们容易混淆的内存概念,Cache名为缓存,Buffer名为缓冲。

CacheBuffer的出现就是为了弥补高速设备和低速设备之间的矛盾而设立的中间层

Cache会将低速设备中常被访问的数据缓存起来,当高速设备需要再次访问这些数据时,会命中Cache中的数据,以减少对低速设备的访问。

Buffer用于缓和高速设备要把数据回写到低速设备时带来的冲击,当数据量比较大时,Buffer能将数据分割成合适的大小,分批回写到磁盘;当数据量比较小的时候,Buffer能将分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,通过“流量整形”提高系统性能。

读取数据具体流程是:先去读取buffer cache,如果cache空间不够,会通过一定的策略将一些过时或多次未被访问的buffer cache清空。程序在下一次访问磁盘时首先查看是否在buffer cache找到所需块,命中可减少访问磁盘时间。不命中时需重新读入buffer cache。

Page cache和Buffer cache的区别

磁盘的操作有逻辑级(文件系统)和物理级(磁盘块),这两种Cache就是分别缓存逻辑和物理级数据的。

假设我们通过文件系统操作文件,那么文件将被缓存到Page Cache,如果需要刷新文件的时候,Page Cache将交给Buffer Cache去完成,因为Buffer Cache就是缓存磁盘块的。

也就是说,直接去操作文件,那就是Page Cache区缓存,用dd等命令直接操作磁盘块,就是Buffer Cache缓存的东西。

Page cache实际上是针对文件系统的,是文件的缓存,在文件层面上的数据会缓存到page cache。文件的逻辑层需要映射到实际的物理磁盘,这种映射关系由文件系统来完成。当page cache的数据需要刷新时,page cache中的数据交给buffer cache,但是这种处理在2.6版本的内核之后就变的很简单了,没有真正意义上的cache操作。

Buffer cache是针对磁盘块的缓存,也就是在没有文件系统的情况下,直接对磁盘进行操作的数据会缓存到buffer cache中,例如,文件系统的元数据都会缓存到buffer cache中。

简单说来,page cache用来缓存文件数据,buffer cache用来缓存磁盘数据。在有文件系统的情况下,对文件操作,那么数据会缓存到page cache,如果直接采用dd等工具对磁盘进行读写,那么数据会缓存到buffer cache。

Buffer(Buffer Cache)以块形式缓冲了块设备的操作,定时或手动的同步到硬盘,它是为了缓冲写操作然后一次性将很多改动写入硬盘,避免频繁写硬盘,提高写入效率。

Cache(Page Cache)以页面形式缓存了文件系统的文件,给需要使用的程序读取,它是为了给读操作提供缓冲,避免频繁读硬盘,提高读取效率。

图解Page Cache与Buffer Cache

程序读取的文件数据保留在Page Cache(页面缓存)中,以便将来读取时重用。如第一次使用findgrep命令时速度比较慢,再次执行就非常快。

Page Cache中的数据需要刷新时,Page Cache中的数据会交给Buffer Cache,而Buffer Cache中的数据会定时刷新到磁盘中,也可通过sync命令将缓冲区里的数据写入磁盘。如果突然断电,Buffer Cache没来得及写入到磁盘中,那么就会发生数据丢失。

在Linux 2.4以前page cache和buffer cache是两个独立的缓存,Linux 2.4开始buffer cache不再是一个独立的缓存,如下图所示的那样,它被包含在page cache中,通过page cache来实现。

Page Cache、Buffer Cache两者融合

介于上述Page Cache、Buffer Cache分离设计的弊端,Linux-2.4版本中对Page Cache、Buffer Cache的实现进行了融合,融合后的Buffer Cache不再以独立的形式存在,Buffer Cache的内容,直接存在于Page Cache中,同时,保留了对Buffer Cache的描述符单元:buffer_head。

两者的关系已经相互融合如下图所示:

一个文件的PageCache(page),通过 buffers 字段能够非常快捷的确定该page对应的buffer_head信息,进而明确该page对应的device, block等信息。

总结

pageCache缓冲了读数据操作,如果要写入数据,pageCache会将数据传递给bufferCache,通过bufferCache缓冲写数据操作。

参考:

linux free 命令 查看内存使用情况

linux 内存查看之 free 命令

Linux系统中的Page cache和Buffer cache

Linux内核Page Cache和Buffer Cache关系及演化历史

三分钟增强内功!Linux中的Buffer与Cache

计算机存储术语: 扇区,磁盘块,页

与[转帖]Linux Page cache和Buffer cache 相似的内容:

[转帖]Linux Page cache和Buffer cache

https://www.cnblogs.com/hongdada/p/16926655.html free 命令常用参数 free 命令用来查看内存使用状况,常用参数如下: -h human-readable 格式打印 -w 把 cache & buffer 分开打印 -t show total f

[转帖]Linux中的Page cache和Buffer cache详解

1、内存情况 在讲解Linux内存管理时已经提到,当你在Linux下频繁存取文件后,即使系统上没有运行许多程序,也会占用大量的物理内存。这是因为当你读写文件的时候,Linux内核为了提高读写的性能和速度,会将文件在内存中进行缓存,这部分内存就是Cache Memory(缓存内存)。即使你的程序运行结

[转帖]Linux系统中的Page cache和Buffer cache

Free命令显示内存 首先,我们来了解下内存的使用情况: Mem:表示物理内存统计 total:表示物理内存总量(total = used + free) used:表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用。 free:未被分配的内存。 sh

[转帖]Linux内存–PageCache

https://plantegg.github.io/2020/11/15/Linux%E5%86%85%E5%AD%98--pagecache/ 本系列有如下几篇 Linux 内存问题汇总 Linux内存–PageCache Linux内存–管理和碎片 Linux内存–HugePage Linux

[转帖]Linux内存–HugePage

https://plantegg.github.io/2020/11/15/Linux%E5%86%85%E5%AD%98--HugePage/ 本系列有如下几篇 Linux 内存问题汇总 Linux内存–PageCache Linux内存–管理和碎片 Linux内存–HugePage Linux内

[转帖]Linux 6种网络IO模型

https://www.jianshu.com/p/c5aa9197ecf4 背景 大多数文件系统的默认 IO 操作都是缓存 IO,又被称作标准IO。在 Linux 的缓存 IO 机制中,操作系统会将 IO 的数据缓存在文件系统的页缓存(page cache )中,也就是说,数据会先被拷贝到操作系统

[转帖]Linux系统:page fault

Linux进程如何访问内存 Linux下,进程并不是直接访问物理内存,而是通过内存管理单元(MMU)来访问内存资源,原因后面会讲到。 为什么需要虚拟内存地址空间 假设某个进程需要4MB的空间,内存假设是1MB的,如果进程直接使用物理地址,这个进程会因为内存不足跑不起来。既然进程不是直接访问物理内存,

[转帖]Linux设备与内存单位-扇区、块、段、页(sector、block、segment、page)

每个概念是对不同的对象而言的,但它们有一定的联系 这些概念的分析背景是Linux下的内存页和磁盘结构 扇区 是硬盘等存储设备传送单位,大小一般为512B 块 是VFS和文件系统的传送单位(所以相关设备也成为块设备),大小必须是2的幂,不能超过页的大小。 段 是一个内存页或内存页的一部分,它包含磁盘上

[转帖]Linux:页表中PGD、PUD、PMD、TLB等概念介绍

1、PGD: Page Global Directory Linux系统中每个进程对应用户空间的pgd是不一样的,但是linux内核 的pgd是一样的。当创建一个新的进程时,都要为新进程创建一个新的页面目录PGD,并从内核的页面目录swapper_pg_dir中复制内核区间页面目录项至新建进程页面目

[转帖]Linux性能优化和内核观测 - 内存篇(一)

内存虚拟内存Linux 采用的是​​虚拟内存​​机制,每个进程都有自己的虚拟内存地址空间,仅当实际使用内存的时候才会映射到物理内存地址之上。这种设计提供了物理内存的超额分配,Linux 中的内存管理机制包括页换出守护进程(page out daemon)、物理换页设备(swap device),以及