1. 说明

  Linux的内核负责硬件管理,资源调度,进程管理,和资源管理等相关工作,其中内存资源管理做为kernel的一项非常重要的工作。kernel在处理文件时,如打开一个文件,会将文件的元数据信息,即文件名,inode等信息记录在buffer中,后续重复读取相同的文件,则直接冲buffer中读取,这样的机制能够提高速度,此外,对于文件的内容,将会记录在cache中保存,对于buffer和cache,内存会有自动清理的机制,如果buffer和cache一直无法释放,可能导致的原因有:内存泄露,应用程序有问题等原因。

2. 现象说明

  生产环境中,使用了两台大硬盘的机器做glusterfs集群,用于openstack的cinder做volume卷的角色,随着时间的推移,发现两台机器的内存利用率超过了95%,上机器上查看时,发现buffer和cache的利用率非常高,如下:

[root@localhost ~]# free -m
             total       used       free     shared    buffers     cached
Mem:         32057      30861       1195          0          6         29
-/+ buffers/cache:          30825       1232            #buffer已经使用了接近30G,只剩下1G左右的空间
Swap:         8191          0       8191

3. 解决方法

  1. 针对buffer和cache过高,只用sync将数据回写到磁盘

[root@localhost ~]# sync && sync && sync
[root@localhost ~]# free -m
             total       used       free     shared    buffers     cached
Mem:         32057      30854       1203          0          7         29
-/+ buffers/cache:          30817       1240            #相比于上次的结果,释放了100M的内存,没有明显的效果
Swap:         8191          0       8191

2. 修改内存对swap的亲和力,转移至swap中

[root@localhost ~]# sysctl -a |grep swap
vm.swappiness = 60                                            #kernel对于swap的亲和力为60,设置为0,则表示直接使用swap空间

#调整swap的亲和力
[root@localhost ~]# sysctl -w vm.swappiness=0
vm.swappiness = 0

[root@localhost ~]# free -m
             total       used       free     shared    buffers     cached
Mem:         32057      30857       1200          0          7         29
-/+ buffers/cache:      30820       1237                      #依旧没有什么明显的效果
Swap:         8191          0       8191

#调整回来
[root@localhost ~]# sysctl -w vm.swappiness=60
vm.swappiness = 60

3. 通过以上的两种方法尝试,都没有达到释放内存的效果,上面的方法,都是比较保守可用的方法,以下通过修改内核参数的方式释放内存

[root@localhost ~]# sysctl -a |grep drop_caches
vm.drop_caches = 0                                            #默认为0,表示默认的机制

#修改为1,释放pagecache,执行前,执行多次sync
[root@localhost ~]# sync && sync && sync && sysctl -w vm.drop_caches=1
vm.drop_caches = 1
[root@localhost ~]# free -m
             total       used       free     shared    buffers     cached
Mem:         32057      30836       1221          0          0         14
-/+ buffers/cache:      30821       1236                       #依旧没有明显的内存资源释放
Swap:         8191          0       8191

#修改为3,释放 pagecache, dentries and inodes
[root@localhost ~]# sync && sync && sync && sysctl -w vm.drop_caches=3    

[root@localhost ~]# free -m
             total       used       free     shared    buffers     cached
Mem:         32057       1715      30342          0         12         34
-/+ buffers/cache:       1667      30389                      #效果立竿见影!!!!,直接释放了30G的内存
Swap:         8188          0       8188

#修改回原始值,千万记得!!
[root@localhost ~]# sysctl -w vm.drop_caches=0

4. 观察监控内存的使用情况

RHCA RH442实战系列(二)之Linux buffer内存释放_第1张图片


4. 参数说明

Drop Caches

Kernels 2.6.16 and newer provide a mechanism to have the kernel drop the page cache and/or inode and dentry caches on command, which can help free up a lot of memory. Now you can throw away that script that allocated a ton of memory just to get rid of the cache...

To use /proc/sys/vm/drop_caches, just echo a number to it.

To free pagecache:

# echo 1 > /proc/sys/vm/drop_caches

To free dentries and inodes:

# echo 2 > /proc/sys/vm/drop_caches

To free pagecache, dentries and inodes:

echo 3 > /proc/sys/vm/drop_caches

This is a non-destructive operation and will only free things that are completely unused. Dirty objects will continue to be in use until written out to disk and are not freeable. If you run "sync" first to flush them out to disk, these drop operations will tend to free more memory.


5. 结论

  关于内存的释放,以上通过暴力的方式,直接释放了保存在内存中的inode和pagecache,关于是否造成数据丢失,还在进步一观察中,如果有发现类似的状况,建议重启进程,或检查应用程序是否有内存泄露等问题,至于是否能够执行,请读者谨慎,仅作参考。