赞
踩
在Linux
系统中,为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回,如果没有则通过驱动程序直接操作磁盘。
缓存机制优点:减少系统调用次数,降低CPU
上下文切换和磁盘访问频率。
CPU
上下文切换:CPU
给每个进程一定的服务时间,当时间片用完后,内核从正在运行的进程中收回处理器,同时把进程当前运行状态保存下来,然后加载下一个任务,这个过程叫做上下文切换。实质上就是被终止运行进程与待运行进程的进程切换。
SWAP
用途:swap
意思是交换分区,通常我们说的虚拟内存,是从硬盘中划分出的一个分区。当物理内存不够用的时候,内核就会释放缓存区(buffer/cache
)里一些长时间不用的程序,然后将这些程序临时放到swap
中,也就是说如果物理内存和缓存区内存不够用的时候,才会用到swap
。
swap
清理:swapoff -a && swapon -a
注意:这样清理有个前提条件,空闲的内存必须比已经使用的swap
空间大。
英文的「cache
」:中国大陆叫「缓存」,台湾叫「快取」。不同地方用语不一,意义是相同的。
Buffers:硬盘块的临时存储大小,注意一点:这里并没有说是写入还是读取。
Cached:作为Cache使用的内存大小
Slab:内核本身使用的Cache大小
SReclaimable:Slab中可以回收的部分
但这里并没有解释清楚buffer
和cache
的区别,英文维基的Cache
条目中,单独有一节是讲述Cache
和Buffer
的差异,大略翻译如下:
“缓冲区(buffer
)”和“缓存(cache
)”的语义并不完全不同; 即便如此,缓存过程和缓冲过程之间的意图也存在根本差异。
从根本上说,缓存cache
实现了重复传输的数据传输的性能提升。虽然缓存系统可以在数据项的初始(通常写入)传输时实现性能提高,但是这种性能提高是由于在缓存系统内的缓冲机制。
使用读缓存,必须至少从其原始位置获取一个数据项至少一次,以便随后读取数据项时,通过从缓存(更快)存储器中读取而不是从数据的原始位置来获取更好的读取性能。利用写缓存,借助于数据项立即存储在高速的缓存存储器中,可以在第一次写入数据项时提高写入性能,之后(或者通过其它后台进程)延迟将数据项写入到目标位置。与严格缓冲相反,缓存过程必须遵循缓存一致性协议(可能是分布式的),以保持缓存与数据原始/目标位置之间的一致性。
另一方面,缓冲buffer
典型的缓存过程中,首次读写的数据项会被缓冲;写入时,通常可以提升要写入数据的应用程序的性能。此外,缓存协议中将多次单独写入通过延迟合并成批量写入,将多个单独读取通过延迟合并成批量读取都是另一种形式的缓冲,因为延迟和合并的原因,对于前面的单个读写操作的性能都可能造成负面影响(所有读写操作的整体性能也有被降低的可能)。实际上,缓存几乎总是涉及某种形式的缓冲,而严格的缓冲不涉及缓存。
传统计算机中,使用内存作为临时缓冲区是因为CPU
的指令不能直接对存储在外围设备中的数据进行寻址。因此需要使用可寻址的内存作为中介来临时存储数据。另外,缓冲区可以用于数据块的组合或者分解(根据存储设备的要求),或者对产生数据进行重新排序后进行传送。此外,整个数据缓冲区通常按顺序传输(例如传输到硬盘),因此缓存可以提高传输性能,减少传输延迟的变化或抖动,不同于缓存的目的是降低延迟。即使将缓冲的数据写入外部设备后再重新读取回缓冲区,依然可以从缓冲机制中获益。
缓存也可以提高传输性能。部分和缓冲类似,来自将多次小量传输合并为一个大数据块的传输。但主要的性能提升是因为可能多次从缓存中读取相同的数据,或者数据写入后很快又被读取回来。缓存的唯一目的是减少对底层较慢存储的访问。缓存通常是一个设计为从相邻层的角度来看是不可见的抽象层。
free
命令用于检测物理内存和交换内存已使用量和可用量(默认单位为KB
)
free -m
使用-m
参数表示以兆字节为单位显示内存
第一部分Mem
行解释:
total:内存总数;
used:已经使用的内存数;
free:空闲的内存数;
shared:当前已经废弃不用;
buffers
Buffer:缓存内存数;
cached Page:缓存内存数。
关系:total = used + free
第二部分(-/+ buffers/cache
)解释:
(-buffers/cache
) used
内存数: 第一部分Mem
行中的 used – buffers – cached
(+buffers/cache
) free
内存数: 第一部分Mem
行中的 free + buffers + cached
可见-buffers/cache
反映的是被程序实实在在吃掉的内存,而+buffers/cache
反映的是可以挪用的内存总数。
第三部分是指交换分区。
缓存(cached
)是把读取过的数据保存起来,重新读取时若命中(找到需要的数据)就不要去读硬盘了,若没有命中就读硬盘。其中的数据会根据读取频率进行组织,把最频繁读取的内容放在最容易找到的位置,把不再读的内容不断往后排,直至从中删除。
缓冲(buffers
)是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。linux
有一个守护进程定期清空缓冲内容(即写入磁盘),也可以通过sync
命令手动清空缓冲。举个例子吧:我这里有一个ext2
的U
盘,我往里面拷贝一个3M
的MP3
,但U
盘的灯没有跳动,过了一会儿(或者手动输入sync
)U盘的灯就跳动起来了。卸载设备时会清空缓冲,所以有些时候卸载一个设备时要等上几秒钟。
修改/etc/sysctl.conf
中的vm.swappiness
右边的数字可以在下次开机时调节swap
使用策略。该数字范围是0~100
,数字越大越倾向于使用swap
。默认为60
,可以改一下试试。
两者都是RAM
中的数据,简单来说,buffer
是即将要被写入磁盘的,而cache
是被从磁盘中读出来的。
buffer
是由各种进程分配的,被用在如输入队列等方面。一个简单的例子如某个进程要求有多个字段读入,在所有字段被读入完整之前,进程把先前读入的字段放在buffer
中保存。
cache
经常被用在磁盘的I/O
请求上,如果有多个进程都要访问某个文件,于是该文件便被做成cache
以便下次被访问,这样可提高系统性能。
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
。它是根据程序的局部性原理而设计的,就是cpu
执行的指令和访问的数据往往在集中的某一块,所以把这块内容放入cache
后,cpu
就不用在访问内存了,这就提高了访问速度。当然若cache
中没有cpu
所需要的内容,还是要访问内存的。从内存读取与磁盘读取角度考虑,cache
可以理解为操作系统为了更高的读取效率,更多的使用内存来缓存可能被再次访问的数据。
Cache
并不是缓存文件的,而是缓存块的(块是I/O
读写最小的单元);Cache
一般会用在I/O
请求上,如果多个进程要访问某个文件,可以把此文件读入Cache
中,这样下一个进程获取CPU
控制权并访问此文件直接从Cache
读取,提高系统性能。
Buffer:缓冲区,一个用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域。通过buffer
可以减少进程间通信需要等待的时间,当存储速度快的设备与存储速度慢的设备进行通信时,存储慢的数据先把数据存放到buffer
,达到一定程度存储快的设备再读取buffer
的数据,在此期间存储快的设备CPU
可以干其他的事情。
Buffer:一般是用在写入磁盘的,例如:某个进程要求多个字段被读入,当所有要求的字段被读入之前已经读入的字段会先放到buffer
中。Buffer
是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。Linux
有一个守护进程定期清空缓冲内容(即写入磁盘),也可以通过sync
命令手动清空缓冲。
cache是高速缓存,用于CPU和内存之间的缓冲;
buffer是I/O缓存,用于内存和硬盘的缓冲;
cache
最初用于cpu cache
,主要原因是cpu
与memory
,由于cpu
快,memory
跟不上,且有些值使用次数多,所以放入cache
中,主要目的是,重复使用,并且一级\二级物理cache
速度快,
buffer
主要用于disk
与 memory
,主要是保护硬盘或减少网络传输的次数(内存数据表现dataSet
).当然也可以提高速度(不会立即写入硬盘或直接从硬盘中读出的数据马上显示),重复使用,最初最主要的目的是保护disk
Free中的buffer和cache:(它们都是占用内存):
buffer : 作为buffer cache的内存,是块设备的读写缓冲区
cache: 作为page cache的内存, 文件系统的cache
如果 cache
的值很大,说明cache
住的文件数很多。如果频繁访问到的文件都能被cache
住,那么磁盘的读IO
比会非常小。
下面通过一些简单通俗的例子来说明下Cache
和Buffer
缓存之间的区别:
1)Cache缓存
假设某地发生了自然灾害(比如地震),居民缺衣少食,于是派救火车去给若干个居民点送水。救火车到达第一个居民点,开闸放水,老百姓就拿着盆盆罐罐来接水。假如说救火车在一个居民点停留100分钟放完了水,然后重新储水花半个小时,再开往下一个居民点。这样一个白天来来来回回的,也就是4-5个居民点。
但我们想想,救火车是何等存在,如果把水龙头完全打开,其强大的水压能轻易冲上10层楼以上, 10分钟就可以把水全部放完。但因为居民是拿盆罐接水,100%打开水龙头那就是给人洗澡了,所以只能打开一小部分(比如10%的流量)。但这样就降低了放水的效率(只有原来的10%了),10分钟变100分钟。
那么,我们是否能改进这个放水的过程,让救火车以最高效率放完水、尽快赶往下一个居民点呢?
方法就是:在居民点建蓄水池。
救火车把水放到蓄水池里,因为是以100%的效率放水,10分钟结束然后走人。居民再从蓄水池里一点一点的接水。
我们分析一下这个例子,就可以知道Cache
的含义了。
救火车要给居民送水,居民要从救火车接水,就是说居民和救火车之间有交互,有联系。但救火车是"高速设备",居民是"低速设备",低速的居民跟不上高速的救火车,所以救火车被迫降低了放水速度以适应居民。为了避免这种情况,在救火车和居民之间多了一层"蓄水池(也就是`Cache`)",它一方面以`100%`的高效和救火车打交道,另一方面以`10%`的低效和居民打交道,这就解放了救火车,让其以最高的效率运行,而不被低速的居民拖后腿,于是救火车只需要在一个居民点停留`10`分钟就可以了。所以说,蓄水池是"活雷锋",把高效留给别人,把低效留给自己。把`10`分钟留给救火车,把`100`分钟留给自己。
从以上例子可以看出,所谓Cache
,就是"为了弥补高速设备和低速设备之间的矛盾"而设立的一个中间层。因为在现实里经常出现高速设备要和低速设备打交道,结果被低速设备拖后腿的情况。Cache
的存在是为了解决什么问题?速度太慢了,要加快速度!
以PC
为例。CPU
速度很快,但CPU
执行的指令是从内存取出的,计算的结果也要写回内存,但内存的响应速度跟不上CPU
。CPU
跟内存说:你把某某地址的指令发给我。内存听到了,但因为速度慢,迟迟不见指令返回,这段时间,CPU
只能无所事事的等待了。这样一来,再快的CPU
也发挥不了效率。
怎么办呢?
在CPU
和内存之间加一块"蓄水池",也就是Cache
(片上缓存),这个Cache
速度比内存快,从Cache
取指令不需要等待。当CPU
要读内存的指令的时候先读Cache
再读内存,但一开始Cache
是空着的,只能从内存取,这时候的确是很慢,CPU
需要等待。但从内存取回的不仅仅是CPU
所需要的指令,还有其它的、当前不需要的指令,然后把这些指令存在Cache
里备用。CPU
再取指令的时候还是先读Cache
,看看里面有没有所需指令,如果碰巧有就直接从Cache
取,不用等待即可返回(命中),这就解放了CPU
,提高了效率。(当然不会是100%
命中,因为Cache
的容量比内存小)
2)Buffer缓存
比如说吐鲁番的葡萄熟了,要用大卡车装葡萄运出去卖。果园的姑娘采摘葡萄,当然不是前手把葡萄摘下来,后手就放到卡车上,而是需要一个中间过程"箩筐":摘葡萄→放到箩筐里→把箩筐里的葡萄倒入卡车。也就是说,虽然最终目的是"把葡萄倒入卡车",但中间必须要经过"箩筐"的转手,这里的箩筐就是Buffer。是"暂时存放物品的空间"。
注意2个关键词:暂时,空间
再换句话说,为了完成最终目标:把葡萄放入卡车的空间,需要暂时把葡萄放入箩筐的空间。
以BT
为例,BT
下载需要长时间的挂机,电脑就有可能24
小时连轴转,但BT
下载的数据是碎片化的,体现在硬盘写入上也是碎片化的,因为硬盘是机械寻址器件,这种碎片化的写入会造成硬盘长时间高负荷的机械运动,造成硬盘过早老化损坏,当年有大量的硬盘因为BT
下载而损坏。于是新出的BT
软件在内存里开辟了Buffer
,数据暂时写入Buffer
,攒到一定的大小(比如512M
)再一次性写入硬盘,这种"化零为整"的写入方式大大降低了硬盘的负荷。这就是:为了完成最终目标:把数据写入硬盘空间,需要暂时写入Buffer
的空间。
3)二者之间的区别总结
Cache
和Buffer
的相同点:都是2
个层面之间的中间层,都是内存。Cache
和Buffer
的不同点:Cache
解决的是时间问题,Buffer
解决的是空间问题。Cache
这个中间层。Buffer
这个中间层。2
个不同维度的问题(时间、空间),恰巧取了同一种解决方法:加入一个中间层,先把数据写到中间层上,然后再写入目标。RAM
”,既然是存储器就有2
个参数:写入的速度有多快(速度),能装多少东西(容量)Cache
利用的是RAM
提供的高读写速度,Buffer
利用的是RAM
提供的存储容量(空间)。a)Buffer(缓冲区)是系统两端处理速度平衡(从长时间尺度上看)时使用的。它的引入是为了减小短期内突发I/O的影响,起到流量整形的作用。比如生产者——消费者问题,他们产生和消耗资源的速度大体接近,加一个buffer可以抵消掉资源刚产生/消耗时的突然变化。
b)Cache(缓存)则是系统两端处理速度不匹配时的一种折衷策略。因为CPU和memory之间的速度差异越来越大,所以人们充分利用数据的局部性(locality)特征,通过使用存储系统分级(memory hierarchy)的策略来减小这种差异带来的影响。
c)假定以后存储器访问变得跟CPU做计算一样快,cache就可以消失,但是buffer依然存在。比如从网络上下载东西,瞬时速率可能会有较大变化,但从长期来看却是稳定的,这样就能通过引入一个buffer使得OS接收数据的速率更稳定,进一步减少对磁盘的伤害。
释放缓存区内存的方法
1)清理pagecache
(页面缓存)
echo 1 > /proc/sys/vm/drop_caches
OR
sysctl -w vm.drop_caches=1
2)清理dentries
(目录缓存)和inodes
echo 2 > /proc/sys/vm/drop_caches
OR
sysctl -w vm.drop_caches=2
3)清理pagecache
、dentries
和inodes
echo 3 > /proc/sys/vm/drop_caches
OR
sysctl -w vm.drop_caches=3
上面三种方式都是临时释放缓存的方法,要想永久释放缓存,需要在
/etc/sysctl.conf
文件中配置:vm.drop_caches=1/2/3
,然后sysctl -p
生效即可!
另外,可以使用sync
命令来清理文件系统缓存,还会清理僵尸(zombie
)对象和它们占用的内存
[root@backup ~]# sync
温馨提示:
上面操作在大多数情况下都不会对系统造成伤害,只会有助于释放不用的内存。
但是如果在执行这些操作时正在写数据,那么实际上在数据到达磁盘之前就将它从文件缓存中清除掉了,这可能会造成很不好的影响。
那么如果避免这种事情发生呢?
因此,这里不得不提一下/proc/sys/vm/vfs_cache_pressure
这个文件,告诉内核,当清理inode/dentry
缓存时应该用什么样的优先级。
[root@backup ~]# cat /proc/sys/vm/vfs_cache_pressure
100
vfs_cache_pressure=100
这个是默认值,内核会尝试重新声明dentries
和inodes
,并采用一种相对于页面缓存和交换缓存比较"合理"的比例。
减少vfs_cache_pressure
的值,会导致内核倾向于保留dentry
和inode
缓存。
增加vfs_cache_pressure
的值,(即超过100
时),则会导致内核倾向于重新声明dentries
和inodes
总之
vfs_cache_pressure
的值:
其实无论vfs_cache_pressure
的值采用什么值,内核清理缓存的速度都是比较低的。
如果将此值设置为10000
,系统将会将缓存减少到一个合理的水平。
附:
这里顺便说下自己遇到的一个内存问题:
IDC机房有一台专门的备份服务器,每天凌晨执行多个备份脚本。某天早上突然发现收到很多条zabbix
监控报警信息:这台备份服务器的内存使用了已超过80%
!
于是,赶紧登陆这台备份服务器,使用free
命令查看内存使用情况:
[root@backup ~]# free -m
total used free shared buffers cached
Mem: 64181 48585 15596 3 2 18
-/+ buffers/cache: 48564 15617
Swap: 32767 0 3276
确实发现内存使用率已超过80%
!但是使用"top
"命令查看,发现此时并没有什么进程在占用内存,并且本机是备份服务器,只有晚上执行备份脚本,
其他时间都没有服务进程在跑!于是尝试手动释放内存:
[root@backup ~]# echo 1 > /proc/sys/vm/drop_caches
[root@backup ~]# echo 2 > /proc/sys/vm/drop_caches
[root@backup ~]# echo 3 > /proc/sys/vm/drop_caches
[root@backup ~]# sync
发现在执行了上面第三条命令后,内存才真正被释放出来了,其他命令都没有起到效果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。