linux下的缓存机制buffer、cache、swap - 运维总结 ["Cannot allocate memory"问题]

网友投稿 943 2022-10-13

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

linux下的缓存机制buffer、cache、swap - 运维总结 ["Cannot allocate memory"问题]

一、缓存机制介绍

在Linux系统中,为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回,如果没有则通过驱动程序直接操作磁盘。缓存机制优点:减少系统调用次数,降低CPU上下文切换和磁盘访问频率。CPU上下文切换:CPU给每个进程一定的服务时间,当时间片用完后,内核从正在运行的进程中收回处理器,同时把进程当前运行状态保存下来,然后加载下一个任务,这个过程叫做上下文切换。实质上就是被终止运行进程与待运行进程的进程切换。

Swap用途:Swap意思是交换分区,通常我们说的虚拟内存,是从硬盘中划分出的一个分区。当物理内存不够用的时候,内核就会释放缓存区(buffers/cache)里一些长时间不用的程序,然后将这些程序临时放到Swap中,也就是说如果物理内存和缓存区内存不够用的时候,才会用到Swap。swap清理:swapoff -a && swapon -a注意:这样清理有个前提条件,空闲的内存必须比已经使用的swap空间大

二、查看缓存区及内存使用情况

对于cpu负载的理解,首先需要搞清楚下面几个问题: 1)系统load高不一定是性能有问题。因为Load高也许是因为在进行cpu密集型的计算 2)系统Load高不一定是CPU能力问题或数量不够。因为Load高只是代表需要运行的队列累计过多了。但队列中的任务实际可能是耗Cpu的,也可能是耗i/0或者其他因素的。 3)系统长期Load高,解决办法不是一味地首先增加CPU因为Load只是表象,不是实质。增加CPU个别情况下会临时看到Load下降,但治标不治本。 4)在Load average 高的情况下需要鉴别系统瓶颈到底是CPU不足,还是io不够快造成或是内存不足造成的。 ===============================================================================================================要想获得服务器的CPU负载情况,有下面几种命令:1)w命令[root@localhost ~]# w 12:12:41 up 167 days, 20:46, 2 users, load average: 0.00, 0.01, 0.05USER TTY FROM LOGIN@ IDLE JCPU PCPU WHATroot pts/0 192.168.1.5 10:01 1.00s 0.11s 0.00s wroot pts/2 192.168.1.5 10:19 1:47m 0.04s 0.04s -bash 2)uptime命令(一般首先会根据最后那个15分钟的load负载为准)[root@localhost ~]# uptime 12:12:55 up 167 days, 20:46, 2 users, load average: 0.00, 0.01, 0.05 3)top命令[root@localhost ~]# toptop - 12:13:22 up 167 days, 20:47, 2 users, load average: 0.00, 0.01, 0.05Tasks: 272 total, 1 running, 271 sleeping, 0 stopped, 0 zombie%Cpu(s): 0.0 us, 0.1 sy, 0.0 ni, 99.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 stKiB Mem : 65759080 total, 58842616 free, 547908 used, 6368556 buff/cacheKiB Swap: 2097148 total, 2097148 free, 0 used. 64264884 avail Mem................对于第一行的解释:12:13:22:表示当前系统时间167 days, 20:47:表示系统已经运行了167天20小时47分钟(在这期间没有重启过)2 users — 当前有2个用户登录系统load average: 0.00, 0.01, 0.05:表示load average后面的三个数分别是1分钟、5分钟、15分钟的负载情况这里需要注意:load average数据是每隔5秒钟检查一次活跃的进程数,然后按特定算法计算出的数值。如果这个数除以逻辑CPU的数量,结果高于5的时候就表明系统在超负荷运转了!!!!!对上面第三行cpu的状态的解释:us(user cpu time):用户态使用的cpu时间比。该值较高时,说明用户进程消耗的 CPU 时间比较多,比如,如果该值长期超过 50%,则需要对程序算法或代码等进行优化。sy(system cpu time):系统态使用的cpu时间比。ni(user nice cpu time):用做nice加权的进程分配的用户态cpu时间比id(idle cpu time):空闲的cpu时间比。如果该值持续为0,同时sy是us的两倍,则通常说明系统则面临着 CPU 资源的短缺。wa(io wait cpu time):cpu等待磁盘写入完成时间。该值较高时,说明IO等待比较严重,这可能磁盘大量作随机访问造成的,也可能是磁盘性能出现了瓶颈。hi(hardware irq):硬中断消耗时间si(software irq):软中断消耗时间st(steal time):虚拟机偷取时间 以上解释的这些参数的值加起来是100%。 4)vmstat[root@localhost ~]# vmstatprocs -----------memory---------------------swap-------io---------system--------cpu-----r b swpd free buff cache si so bi bo in cs us sy id wa st3 0 0 1639792 724280 4854236 0 0 4 34 4 0 19 45 35 0 0 解释说明:-----------------------------procs部分的解释r 列表示运行和等待cpu时间片的进程数,如果长期大于1,说明cpu不足,需要增加cpu。b 列表示在等待资源的进程数,比如正在等待I/O、或者内存交换等。-----------------------------cpu部分的解释us 列显示了用户方式下所花费 CPU 时间的百分比。us的值比较高时,说明用户进程消耗的cpu时间多,但是如果长期大于50%,需要考虑优化用户的程序。sy 列显示了内核进程所花费的cpu时间的百分比。这里us + sy的参考值为80%,如果us+sy 大于 80%说明可能存在CPU不足。wa 列显示了IO等待所占用的CPU时间的百分比。这里wa的参考值为30%,如果wa超过30%,说明IO等待严重,这可能是磁盘大量随机访问造成的,也可能磁盘或者 磁盘访问控制器的带宽瓶颈造成的(主要是块操作)。id 列显示了cpu处在空闲状态的时间百分比-----------------------------system部分的解释in 列表示在某一时间间隔中观测到的每秒设备中断数。cs列表示每秒产生的上下文切换次数,如当 cs 比磁盘 I/O 和网络信息包速率高得多,都应进行进一步调查。-----------------------------memory部分的解释swpd 切换到内存交换区的内存数量(k表示)。如果swpd的值不为0,或者比较大,比如超过了100m,只要si、so的值长期为0,系统性能还是正常free 当前的空闲页面列表中内存数量(k表示)buff 作为buffer cache的内存数量,一般对块设备的读写才需要缓冲。cache: 作为page cache的内存数量,一般作为文件系统的cache,如果cache较大,说明用到cache的文件较多,如果此时IO中bi比较小,说明文件系统效率比较好。-----------------------------swap部分的解释si 由内存进入内存交换区数量。so由内存交换区进入内存数量。-----------------------------IO部分的解释bi 从块设备读入数据的总量(读磁盘)(每秒kb)。bo 块设备写入数据的总量(写磁盘)(每秒kb) 5)也可以使用dstat命令查看cpu信息[root@localhost ~]# dstat----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--usr sys idl wai hiq siq| read writ| recv send| in out | int csw 19 45 35 0 0 0| 30k 265k| 0 0 | 0 0 |9025 12k 9 18 73 0 0 0| 0 144k|2578k 65k| 0 0 |3956 4343 6)可以使用iostat查看IO负载[root@localhost ~]# iostat 1 1Linux 2.6.32-696.16.1.el6.x86_64 (nc-ftp01.kevin.cn) 2017年12月29日 _x86_64_ (4 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 19.32 0.00 45.44 0.06 0.26 34.93 Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtnxvda 14.17 29.94 265.17 63120486 558975100 解释说明:avg-cpu: 总体cpu使用情况统计信息,对于多核cpu,这里为所有cpu的平均值%user: 在用户级别运行所使用的CPU的百分比.%nice: nice操作所使用的CPU的百分比.%sys: 在系统级别(kernel)运行所使用CPU的百分比.%iowait: CPU等待硬件I/O时,所占用CPU百分比.%idle: CPU空闲时间的百分比. Device段:各磁盘设备的IO统计信息tps: 每秒钟发送到的I/O请求数.Blk_read /s: 每秒读取的block数.Blk_wrtn/s: 每秒写入的block数.Blk_read: 读入的block总数.Blk_wrtn: 写入的block总数. [root@localhost ~]# iostat -x -k -d 1Linux 2.6.32-696.el6.x86_64 (centos6-vm02) 01/04/2018 _x86_64_ (4 CPU) Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %utilscd0 0.00 0.00 0.00 0.00 0.00 0.00 8.00 0.00 0.36 0.36 0.00 0.36 0.00vda 0.01 0.13 0.04 0.13 0.60 0.89 18.12 0.00 2.78 0.19 3.53 2.55 0.04dm-0 0.00 0.00 0.04 0.22 0.58 0.88 11.25 0.00 3.27 0.25 3.82 1.61 0.04dm-1 0.00 0.00 0.00 0.00 0.00 0.00 8.00 0.00 0.13 0.13 0.00 0.04 0.00dm-2 0.00 0.00 0.00 0.00 0.00 0.00 7.91 0.00 0.19 0.10 5.00 0.16 0.00 解释说明:rrqm/s: 每秒对该设备的读请求被合并次数,文件系统会对读取同块(block)的请求进行合并wrqm/s: 每秒对该设备的写请求被合并次数r/s: 每秒完成的读次数w/s: 每秒完成的写次数rkB/s: 每秒读数据量(kB为单位)wkB/s: 每秒写数据量(kB为单位)avgrq-sz:平均每次IO操作的数据量(扇区数为单位)avgqu-sz: 平均等待处理的IO请求队列长度await: 平均每次IO请求等待时间(包括等待时间和处理时间,毫秒为单位)svctm: 平均每次IO请求的处理时间(毫秒为单位)%util: 采用周期内用于IO操作的时间比率,即IO队列非空的时间比率 如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。idle小于70% IO压力就较大了,一般读取速度有较多的wait。同时可以结合vmstat 查看查看b参数(等待资源的进程数)和wa参数(IO等待所占用的CPU时间的百分比,高过30%时IO压力高)

三、buffers和cached解释

缓存(cached)是把读取过的数据保存起来,重新读取时若命中(找到需要的数据)就不要去读硬盘了,若没有命中就读硬盘。其中的数据会根据读取频率进行组织,把最频繁读取的内容放在最容易找到的位置,把不再读的内容不断往后排,直至从中删除。

缓冲(buffers)是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。linux有一个守护进程定期清空缓冲内容(即写入磁盘),也可以通过sync命令手动清空缓冲。举个例子吧:我这里有一个ext2的U盘,我往里面cp一个3M的MP3,但U盘的灯没有跳动,过了一会儿(或者手动输入sync)U盘的灯就跳动起来了。卸载设备时会清空缓冲,所以有些时候卸载一个设备时要等上几秒钟。

修改/etc/sysctl.conf中的vm.swappiness右边的数字可以在下次开机时调节swap使用策略。该数字范围是0~100,数字越大越倾向于使用swap。默认为60,可以改一下试试。–两者都是RAM中的数据。

两者都是RAM中的数据,简单来说,buffer是即将要被写入磁盘的,而cache是被从磁盘中读出来的。buffer是由各种进程分配的,被用在如输入队列等方面。一个简单的例子如某个进程要求有多个字段读入,在所有字段被读入完整之前,进程把先前读入的字段放在buffer中保存。cache经常被用在磁盘的I/O请求上,如果有多个进程都要访问某个文件,于是该文件便被做成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 bi会非常小。

========================================================下面通过一些简单通俗的例子来说明下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提供的存储容量(空间)。

简言之:1. Buffer(缓冲区)是系统两端处理速度平衡(从长时间尺度上看)时使用的。它的引入是为了减小短期内突发I/O的影响,起到流量整形的作用。比如生产者——消费者问题,他们产生和消耗资源的速度大体接近,加一个buffer可以抵消掉资源刚产生/消耗时的突然变化。2. Cache(缓存)则是系统两端处理速度不匹配时的一种折衷策略。因为CPU和memory之间的速度差异越来越大,所以人们充分利用数据的局部性(locality)特征,通过使用存储系统分级(memory hierarchy)的策略来减小这种差异带来的影响。3. 假定以后存储器访问变得跟CPU做计算一样快,cache就可以消失,但是buffer依然存在。比如从网络上下载东西,瞬时速率可能会有较大变化,但从长期来看却是稳定的,这样就能通过引入一个buffer使得OS接收数据的速率更稳定,进一步减少对磁盘的伤害。

四、手动清理缓存

五、"Cannot allocate memory"问题

上一篇:如何在 Linux 下快速找到被删除的文件?
下一篇:《Nutanix 圣经》第三部分:Acropolis
相关文章

 发表评论

暂时没有评论,来抢沙发吧~