在Linux系统中,为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回,如果没有则通过驱动程序直接操作磁盘。
内存查看
当我们使用 free -h
命令时,会显示如下的信息
total used free shared buff/cache available
Mem: 15G 1.0G 9.3G 1.9M 5.4G 14G
Swap: 0B 0B 0B
total:内存总数;used:已经使用的内存数;free:空闲的内存数;shared:当前已经废弃不用;buff/cache:缓存内存数;
关系:total = used + freeSwap用途:Swap意思是交换分区,通常我们说的虚拟内存,是从硬盘中划分出的一个分区。当物理内存不够用的时候,内核就会释放缓存区(buffers/cache)里一些长时间不用的程序,然后将这些程序临时放到Swap中,也就是说如果物理内存和缓存区内存不够用的时候,才会用到Swap。
swap清理:swapoff -a && swapon -a
cache && buffer
cache
缓存(cached)是把读取过的数据保存起来,重新读取时若命中(找到需要的数据)就不要去读硬盘了,若没有命中就读硬盘。其中的数据会根据读取频率进行组织,把最频繁读取的内容放在最容易找到的位置,把不再读的内容不断往后排,直至从中删除。
Cache并不是缓存文件的,而是缓存块的(块是I/O读写最小的单元);Cache一般会用在I/O请求上,如果多个进程要访问某个文件,可以把此文件读入Cache中,这样下一个进程获取CPU控制权并访问此文件直接从Cache读取,提高系统性能。
Cache 作用域在于 Cpu 与内存之间
buffer
缓冲(buffers)是根据磁盘的读写设计的,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能。当存储速度快的设备与存储速度慢的设备进行通信时,存储慢的数据先把数据存放到buffer,达到一定程度存储快的设备再读取buffer的数据,在此期间存储快的设备CPU可以干其他的事情。
linux有一个守护进程定期清空缓冲内容(即写入磁盘),也可以通过sync命令手动清空缓冲。
修改/etc/sysctl.conf中的vm.swappiness右边的数字可以在下次开机时调节swap使用策略。该数字范围是0~100,数字越大越倾向于使用swap。默认为60,可以改一下试试。–两者都是RAM中的数据。
cache vs buffer
cache最初用于cpu cache,主要原因是cpu 与memory,由于cpu快,memory跟不上,且有些值使用次数多,所以放入cache中,主要目的是,重复使用,并且一级二级物理cache速度快,
buffer主要用于disk与 memory,主要是保护硬盘或减少网络传输的次数(内存数据表现dataSet).当然也可以提高速度(不会立即写入硬盘或直接从硬盘中读出的数据马上显示),重复使用,最初最主要的目的是保护disk。
cache 也可以用于写,buffer 也可以用于读,两者并未有实实在在明显的界限。
swap
除了以上两种,linux 还引入了 swap 技术,swap的作用类似Windows系统下的“虚拟内存”。当物理内存不足时,拿出部分硬盘空间当SWAP分区(虚拟成内存)使用,从而解决内存容量不足的情况。
当程序向OS请求内存资源时,OS发现内存不足,则会把内存中暂时不用的数据交换出去,放在SWAP分区中,这个过程称为SWAP OUT。当程序又需要这些数据且OS发现还有空闲物理内存时,又会把SWAP分区中的数据交换回物理内存中,这个过程称为SWAP IN。
那么我们在使用 docker 和 K8s 的时候,为什么要关闭 swap 特性呢?主要还是希望获取更高的性能。kubernetes的思想是将实例紧密打包为尽可能接近100%的利用率。所有部署都应固定有CPU /内存限制。因此,如果调度程序将Pod发送到计算机,则绝对不要使用swap。
手动清理释放
释放缓存区内存的方法1)清理pagecache(页面缓存)
echo 1 > /proc/sys/vm/drop_caches
# 或者
sysctl -w vm.drop_caches=1
2)清理dentries(目录缓存)和inodes
echo 2 > /proc/sys/vm/drop_caches
#或者
sysctl -w vm.drop_caches=2
3)清理pagecache、dentries和inodes
echo 3 > /proc/sys/vm/drop_caches
#或者
sysctl -w vm.drop_caches=3
上面三种方式都是临时释放缓存的方法,要想永久释放缓存,需要在/etc/sysctl.conf
文件中配置:
vm.drop_caches=1/2/3
然后sysctl -p
生效
另外,可以使用sync
命令来清理文件系统缓存,还会清理僵尸(zombie)对象和它们占用的内存
值得一提
上面操作在大多数情况下都不会对系统造成伤害,只会有助于释放不用的内存。但是如果在执行这些操作时正在写数据,那么实际上在数据到达磁盘之前就将它从文件缓存中清除掉了,这可能会造成很不好的影响。
那么如果避免这种事情发生呢?因此,这里不得不提一下/proc/sys/vm/vfs_cache_pressure
这个文件,告诉内核,当清理inoe/dentry
缓存时应该用什么样的优先级。
> 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
的值:小于100的值不会导致缓存的大量减少超过100的值则会告诉内核你希望以高优先级来清理缓存。
其实无论vfs_cache_pressure
的值采用什么值,内核清理缓存的速度都是比较低的。如果将此值设置为10000,系统将会将缓存减少到一个合理的水平。
如果喜欢,请关注我的公众号,或者查看我的博客 http://packyzbq.coding.me. 我会不定时的发送我自己的学习记录,大家互相学习交流哈~
http://weixin.qq.com/r/Zkw2LtvEk4bsrZ9N9xl0 (二维码自动识别)