【Linux】基于Linux的buffer和cache学习

缓存(cached)是把读取过的数据保存起来,重新读取时若命中(找到需要的数据)就不要去读硬盘了,若没有命中就读硬盘。其中的数据会根据读取频率进行组织,把最频繁读取的内容放在最容易找到的位置,把不再读的内容不断往后排,直至从中删除。
缓冲(buffers)是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。linux有一个守护进程定期清空缓冲内容(即写入磁盘),也可以通过sync命令手动清空缓冲。举个例子吧:我这里有一个ext2的U盘,我往里面cp一个3M的MP3,但U盘的灯没有跳动,过了一会儿(或者手动输入sync)U盘的灯就跳动起来了。卸载设备时会清空缓冲,所以有些时候卸载一个设备时要等上几秒钟。
修改/etc/sysctl.conf中的vm.swappiness右边的数字可以在下次开机时调节swap使用策略。该数字范围是0~100,数字越大越倾向于使用swap。默认为60,可以改一下试试。–两者都是RAM中的数据。
简单来说,buffer是即将要被写入磁盘的,而cache是被从磁盘中读出来的。
buffer是由各种进程分配的,被用在如输入队列等方面。一个简单的例子如某个进程要求有多个字段读入,在所有字段被读入完整之前,进程把先前读入的字段放在buffer中保存。
cache经常被用在磁盘的I/O请求上,如果有多个进程都要访问某个文件,于是该文件便被做成cache以方便下次被访问,这样可提高系统性能。

[root@dbop-ft-db-68 mysqlData]# cat /proc/meminfo
MemTotal:       74086996 kB
MemFree:        44225596 kB
Buffers:          229884 kB
Cached:         23017008 kB
SwapCached:            0 kB
Active:          6376068 kB
Inactive:       21270284 kB
Active(anon):    4399776 kB
Inactive(anon):     2028 kB
Active(file):    1976292 kB
Inactive(file): 21268256 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:       4399440 kB
Mapped:            18492 kB
Shmem:              2364 kB
Slab:            1946516 kB
SReclaimable:     697104 kB
SUnreclaim:      1249412 kB
KernelStack:        7480 kB
PageTables:        12492 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    37043496 kB
Committed_AS:   48149240 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      491216 kB
VmallocChunk:   34290538544 kB
HardwareCorrupted:     0 kB
AnonHugePages:   4323328 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:        8192 kB
DirectMap2M:     4161536 kB
DirectMap1G:    71303168 kB

理解linux内存管理,需要深入了解linux内存的各个参数含义和规则,下面介绍一下Linux操作系统中内存buffer和cache的区别。
free 命令相对于top 提供了更简洁的查看系统内存使用情况:

[root@dbop-ft-db-68 ~]# free -mt
             total       used       free     shared    buffers     cached
Mem:         72350      29163      43187          0        224      22477
-/+ buffers/cache:       6461      65889
Swap:            0          0          0
Total:       72350      29163      43187

Mem:表示物理内存统计
-/+ buffers/cached:表示物理内存的缓存统计
Swap:表示硬盘上交换分区的使用情况,这里我们不去关心。
系统的总物理内存:3886M,但系统当前真正可用的内存b并不是第一行free 标记的 26M,它仅代表未被分配的内存。
我们使用total1、used1、free1、used2、free2 等名称来代表上面统计数据的各值,1、2 分别代表第一行和第二行的数据。
total1:表示物理内存总量。
used1:表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用。
free1:未被分配的内存。
shared1:共享内存,一般系统不会用到,这里也不讨论。
buffers1:系统分配但未被使用的buffers 数量。
cached1:系统分配但未被使用的cache 数量。buffer 与cache 的区别见后面。
used2:实际使用的buffers 与cache 总量,也是实际使用的内存总量。
free2:未被使用的buffers 与cache 和未被分配的内存之和,这就是系统当前实际可用内存。
可以整理出如下等式:
total1 = used1 + free1total1 = used2 + free2used1 = buffers1 + cached1 + used2free2 = buffers1 + cached1 + free1
buffer 与cache 的区别
A buffer is something that has yet to be "written" to disk. A cache is something that has been "read" from the disk and stored for later use.
更详细的解释参考:Difference Between Buffer and Cache
对于共享内存(Shared memory),主要用于在UNIX 环境下不同进程之间共享数据,是进程间通信的一种方法,一般的应用程序不会申请使用共享内存,笔者也没有去验证共享内存对上面等式的影响。如果你有兴趣,请参考:What is Shared Memory?
cache 和 buffer的区别:
Cache:高速缓存,是位于CPU与主内存间的一种容量较小但速度很高的存储器。由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,Cache中保存着CPU刚用过或循环使用的一部分数据,当CPU再次使用该部分数据时可从Cache中直接调用,这样就减少了CPU的等待时间,提高了系统的效率。Cache又分为一级Cache(L1 Cache)和二级Cache(L2 Cache),L1 Cache集成在CPU内部,L2 Cache早期一般是焊在主板上,现在也都集成在CPU内部,常见的容量有256KB或512KB L2 Cache。
Buffer:缓冲区,一个用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域。通过缓冲区,可以使进程之间的相互等待变少,从而使从速度慢的设备读入数据时,速度快的设备的操作进程不发生间断。
Free中的buffer和cache:(它们都是占用内存):
buffer : 作为buffer cache的内存,是块设备的读写缓冲区
cache: 作为page cache的内存, 文件系统的cache
如果 cache 的值很大,说明cache住的文件数很多。如果频繁访问到的文件都能被cache住,那么磁盘的读IO bi会非常小。
Page cache和buffer cache到底有什么区别呢?很多时候我们不知道系统在做IO操作的时候到底是走了page cache还是buffer cache?其实,buffer cache和page cache是Linux中两个比较简单的概念,在此对其总结说明。
Page cache是vfs文件系统层的cache,例如 对于一个ext3文件系统而言,每个文件都会有一棵radix树管理文件的缓存页,这些被管理的缓存页被称之为page cache。所以,page cache是针对文件系统而言的。例如,ext3文件系统的页缓存就是page cache。Buffer cache是针对设备的,每个设备都会有一棵radix树管理数据缓存块,这些缓存块被称之为buffer cache。通常对于ext3文件系统而言,page cache的大小为4KB,所以ext3每次操作的数据块大小都是4KB的整数倍。Buffer cache的缓存块大小通常由块设备的大小来决定,取值范围在512B~4KB之间,取块设备大小的最大公约数。具体关于buffer cache的块大小问题可以参见我的另一篇博文《Linux中Buffer cache性能问题一探究竟》见 http://www.linuxidc.com/Linux/2013-01/77573.htm 。
这里我们可以通过一个小实验来观察一下buffer cache和page cache的差别。运行top命令,我们可以看到实验机器当前内存使用情况:

top - 15:57:14 up 21 days, 25 min,  2 users,  load average: 0.24, 0.11, 0.04
Tasks: 851 total,   1 running, 850 sleeping,   0 stopped,   0 zombie
Cpu(s):  2.6%us,  0.1%sy,  0.0%ni, 97.2%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  74086996k total, 10305980k used, 63781016k free,   292176k buffers
Swap:        0k total,        0k used,        0k free,  4209584k cached

 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
30612 mysql     20   0 46.1g 3.9g 5768 S 98.2  5.5   1:02.17 mysqld  

可以看出内存总容量为72GB,page cache用了将近9GB(10305980-292176K),buffer cache用了285M(292176K),其余61GB(6255076K)空闲剩余。在这种情况下,如果对磁盘进行裸盘写操作,即运行如下命令:dd if=/dev/zero of=/mysqlData/test.txt bs=4M count=4096
那么,我么可以通过top命令发现,buffer cache的容量越来越大,空闲内存越来越少,相当一部分内存被buffer cache占用,并且在IO操作的过程中发现bdi(flush-253:0)线程在繁忙的进行数据回刷操作。

top - 16:08:59 up 21 days, 37 min,  2 users,  load average: 0.45, 0.12, 0.04
Tasks: 851 total,   2 running, 849 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  5.0%sy,  0.0%ni, 91.9%id,  3.1%wa,  0.0%hi,  0.1%si,  0.0%st
Mem:  74086996k total, 18269492k used, 55817504k free,   238256k buffers
Swap:        0k total,        0k used,        0k free, 11684712k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                30814 root      20   0  106m 4744  556 R 99.5  0.0   0:15.81 dd        
30815 root      20   0     0    0    0 D 18.8  0.0   0:01.96 flush-253:0              
 4741 root      20   0     0    0    0 S  5.3  0.0   0:00.56 xfsdatad/4             
 4761 root      20   0     0    0    0 S  4.9  0.0   0:00.23 xfsdatad/24 

经过一段时间以后,大约227M(238256KB)的内存被buffer cache占用,53.2G(55817504KB)内存空闲,其余大约17GB(18269492K-238256K)的内存还是被page cache占用。通过这个实验,可以说明对于裸盘的读写操作会占用buffer cache,并且当读写操作完成之后,这些buffer cache会归还给系统。为了验证page cache的占用情况,我做了文件系统级的读写操作,运行如下命令进行文件系统写操作:cp test.txt ./test1.txt 
这是一次文件拷贝操作,因此会采用page cache对文件数据进行缓存。通过top工具我们可以看出在数据拷贝的过程中,page cache的容量越来越大,空闲内存数量急剧下降,而buffer cache保持不变。

top - 16:18:34 up 21 days, 46 min,  2 users,  load average: 0.55, 0.22, 0.11
Tasks: 852 total,   1 running, 851 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  2.1%sy,  0.0%ni, 96.9%id,  0.8%wa,  0.0%hi,  0.1%si,  0.0%st
Mem:  74086996k total, 28567280k used, 45519716k free,   229884k buffers
Swap:        0k total,        0k used,        0k free, 21798656k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
30909 root      20   0  110m  860  696 D 66.3  0.0   0:18.48 cp
30886 root      20   0     0    0    0 S  8.6  0.0   0:00.26 flush-253:0
 4741 root      20   0     0    0    0 S  4.0  0.0   0:00.77 xfsdatad/4
30904 root      20   0 15552 1808  928 R  1.0  0.0   0:00.39 top

拷贝一定时间之后,空闲内存将为43.4GB(45519716K),文件系统page cache增长为将近27GB(28567280K-229884K),buffer cache维持在224MB左右(229884K)。
由此我们可以得出,page cache和buffer cache最大的差别在于:page cache是对文件数据的缓存;buffer cache是对设备数据的缓存。两者在实现上差别不是很大,都是采用radix树进行管理。
Buffer Cache又称bcache,其中文名称为缓冲器高速缓冲存储器,简称缓冲器高缓。另外,buffer cache按照其工作原理,又被称为块高缓。
参考:
http://baike.baidu.com/view/1113956.htm
1、功能:在linux读写文件时,它用于缓存物理磁盘上的磁盘块,从而加快对磁盘上数据的访问。
2、大小:buffer cache的内容对应磁盘上一个块(block),块通常为1K,都是连续的。
在linux下,为了更有效的使用物理内存,操作系统自动使用所有空闲内存作为Buffer Cache使用。当程序需要更多内存时,操作系统会自动减小Cache的大小。
在linux下,可通过命令cat /proc/meminfo和free -m查看buffer cache的内存使用情况。

buffer cache的lru list和dirty list

http://www.itpub.net/thread-1086537-1-1.html

http://blog.chinaunix.net/uid-23582874-id-3483624.html

原文地址:https://www.cnblogs.com/jiangxu67/p/3501954.html