阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Linux服务器Cache占用过多内存导致系统内存不足问题的排查解决

188次阅读
没有评论

共计 6069 个字符,预计需要花费 16 分钟才能阅读完成。

问题描述

Linux 服务器内存使用量超过阈值,触发报警。

问题排查

首先,通过 free 命令观察系统的内存使用情况,显示如下:

total       used       free     shared    buffers     cached
Mem:      24675796   24587144      88652          0     357012    1612488
-/+ buffers/cache:   22617644    2058152
Swap:      2096472     108224    1988248

其中,可以看出内存总量为 24675796KB,已使用 22617644KB,只剩余 2058152KB。

然后,接着通过 top 命令,shift + M 按内存排序后,观察系统中使用内存最大的进程情况,发现只占用了 18GB 内存,其他进程均很小,可忽略。

因此,还有将近 4GB 内存(22617644KB-18GB,约 4GB)用到什么地方了呢?

进一步,通过 cat /proc/meminfo 发现,其中有将近 4GB(3688732 KB)的 Slab 内存:

......
Mapped:          25212 kB
Slab:          3688732 kB
PageTables:      43524 kB
......

Slab 是用于存放内核数据结构缓存,再通过 slabtop 命令查看这部分内存的使用情况:

OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
13926348 13926348 100%    0.21K 773686       18   3494744K dentry_cache
334040 262056  78%    0.09K   8351       40     33404K buffer_head
151040 150537  99%    0.74K  30208        5    120832K ext3_inode_cache

发现其中大部分(大约 3.5GB)都是用于了dentry_cache

问题解决

1. 修改 /proc/sys/vm/drop_caches,释放 Slab 占用的 cache 内存空间(参考 drop_caches 的官方文档):

Linux 服务器 Cache 占用过多内存导致系统内存不足问题的排查解决
Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free.
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
As this is a non-destructive operation, and dirty objects are notfreeable, the user should run "sync" first in order to make sure allcached objects are freed.
This tunable was added in 2.6.16.
Linux 服务器 Cache 占用过多内存导致系统内存不足问题的排查解决

2. 方法 1 需要用户具有 root 权限,如果不是 root,但有 sudo 权限,可以通过 sysctl 命令进行设置:

$sync
$sudo sysctl -w vm.drop_caches=3
$sudo sysctl -w vm.drop_caches=0 #recovery drop_caches

操作后可以通过 sudo sysctl -a | grep drop_caches 查看是否生效。

3. 修改 /proc/sys/vm/vfs_cache_pressure,调整清理 inode/dentry caches 的优先级(默认为 100),LinuxInsight 中有相关的解释:

At the default value of vfs_cache_pressure = 100 the kernel will attempt to reclaim dentries and inodes at a“fair”rate with respect to pagecache and swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer to retain dentry and inode caches. Increasing vfs_cache_pressure beyond 100 causes the kernel to prefer to reclaim dentries and inodes.

具体的设置方法,可以参考方法 1 或者方法 2 均可。

参考资料

https://www.kernel.org/doc/Documentation/sysctl/vm.txt

http://major.io/2008/12/03/reducing-inode-and-dentry-caches-to-keep-oom-killer-at-bay/

http://linux-mm.org/Drop_Caches

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2015-08/121565p2.htm

前面文章里已经描述了具体遇到的问题及一些解决方法。但是还有些疑问点没有搞清楚,进一步学习了 Linux 系统下内存的分配使用机制,这里有两个资料讲的比较全面:

Where is the memory going? Memory waste under Linux

Where is the memory going?Memory usage in the 2.6 kernel

以下记录的是进一步排查的进展情况。

更深层次的原因

前一篇文章里排查到 Linux 系统中有大量的 dentry_cache 占用内存,为什么会有如此多的dentry_cach e 呢?

1. 首先,弄清楚 dentry_cache 的概念及作用:目录项高速缓存,是 Linux 为了提高目录项对象的处理效率而设计的;它记录了目录项到 inode 的映射关系。因此,当应用程序发起 stat 系统调用时,就会创建对应的 dentry_cache 项(更进一步,如果每次 stat 的文件都是不存在的文件,那么总是会有大量新的 dentry_cache 项被创建)。

2. 当前服务器是 storm 集群的节点,首先想到了 storm 相关的工作进程,strace 一下 storm 的 worker 进程发现其中有非常频繁的 stat 系统调用发生,而且 stat 的文件总是新的文件名:

sudo strace -fp <pid> -e trace=stat

3. 进一步观察到 storm 的 worker 进程会在本地目录下频繁的创建、打开、关闭、删除心跳文件,每秒钟一个新的文件名:

sudo strace -fp <pid> -e trace=open,stat,close,unlink

以上就是系统中为何有如此多的 dentry_cache 的原因所在。

一个奇怪的现象

通过观察 /proc/meminfo 发现,slab 内存分为两部分:

SReclaimable // 可回收的 slab
SUnreclaim // 不可回收的 slab

当时服务器的现状是:slab 部分占用的内存,大部分显示的都是 SReclaimable,也就是说可以被回收的。

但是通过 slabtop 观察到 slab 内存中最主要的部分(dentry_cache)的 OBJS 几乎都是 ACTIVE 的,显示 100% 处于被使用状态。

OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
13926348 13926348 100%    0.21K 773686       18   3494744K dentry_cache
334040 262056  78%    0.09K   8351       40     33404K buffer_head
151040 150537  99%    0.74K  30208        5    120832K ext3_inode_cache

为什么显示可回收的,但是又处于 ACTIVE 状态呢?求 Linux 内核达人看到后热心解释下:(

会不会由于是 ACTIVE 状态,导致 dcache 没有被自动回收释放掉呢?

让系统自动回收 dcache

上一小节,我们已经提到,服务器上大部分的 slab 内存是 SReclaimable 可回收状态的,那么,我们能不能交给操作系统让他在某个时机自动触发回收操作呢?答案是肯定的。

查了一些关于 Linux dcache 的相关资料,发现操作系统会在到了内存临界阈值后,触发 kswapd 内核进程工作才进行释放,这个阈值的计算方法如下:

1. 首先,grep low /proc/zoneinfo,得到如下结果:

low      1
        low      380
        low      12067

2. 将以上 3 列加起来,乘以 4KB,就是这个阈值,通过这个方法计算后发现当前服务器的回收阈值只有 48MB,因此很难看到这一现象,实际中可能等不到回收,操作系统就会 hang 住没响应了。

3. 可以通过以下方法调大这个阈值:将 vm.extra_free_kbytes 设置为vm.min_free_kbytes 和一样大,则 /proc/zoneinfo 中对应的 low 阈值就会增大一倍,同时 high 阈值也会随之增长,以此类推。

$ sudo sysctl -a | grep free_kbytes       
vm.min_free_kbytes = 39847
vm.extra_free_kbytes = 0
$ sudo sysctl -w vm.extra_free_kbytes=836787 ######1GB

 4. 举个例子,当 low 阈值被设置为 1GB 的时候,当系统 free 的内存小于 1GB 时,观察到 kswapd 进程开始工作(进程状态从 Sleeping 变为 Running),同时 dcache 开始被系统回收,直到系统 free 的内存介于 low 阈值和 high 阈值之间,停止回收。

本文永久更新链接地址:http://www.linuxidc.com/Linux/2015-08/121565.htm

问题描述

Linux 服务器内存使用量超过阈值,触发报警。

问题排查

首先,通过 free 命令观察系统的内存使用情况,显示如下:

total       used       free     shared    buffers     cached
Mem:      24675796   24587144      88652          0     357012    1612488
-/+ buffers/cache:   22617644    2058152
Swap:      2096472     108224    1988248

其中,可以看出内存总量为 24675796KB,已使用 22617644KB,只剩余 2058152KB。

然后,接着通过 top 命令,shift + M 按内存排序后,观察系统中使用内存最大的进程情况,发现只占用了 18GB 内存,其他进程均很小,可忽略。

因此,还有将近 4GB 内存(22617644KB-18GB,约 4GB)用到什么地方了呢?

进一步,通过 cat /proc/meminfo 发现,其中有将近 4GB(3688732 KB)的 Slab 内存:

......
Mapped:          25212 kB
Slab:          3688732 kB
PageTables:      43524 kB
......

Slab 是用于存放内核数据结构缓存,再通过 slabtop 命令查看这部分内存的使用情况:

OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
13926348 13926348 100%    0.21K 773686       18   3494744K dentry_cache
334040 262056  78%    0.09K   8351       40     33404K buffer_head
151040 150537  99%    0.74K  30208        5    120832K ext3_inode_cache

发现其中大部分(大约 3.5GB)都是用于了dentry_cache

问题解决

1. 修改 /proc/sys/vm/drop_caches,释放 Slab 占用的 cache 内存空间(参考 drop_caches 的官方文档):

Linux 服务器 Cache 占用过多内存导致系统内存不足问题的排查解决
Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free.
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
As this is a non-destructive operation, and dirty objects are notfreeable, the user should run "sync" first in order to make sure allcached objects are freed.
This tunable was added in 2.6.16.
Linux 服务器 Cache 占用过多内存导致系统内存不足问题的排查解决

2. 方法 1 需要用户具有 root 权限,如果不是 root,但有 sudo 权限,可以通过 sysctl 命令进行设置:

$sync
$sudo sysctl -w vm.drop_caches=3
$sudo sysctl -w vm.drop_caches=0 #recovery drop_caches

操作后可以通过 sudo sysctl -a | grep drop_caches 查看是否生效。

3. 修改 /proc/sys/vm/vfs_cache_pressure,调整清理 inode/dentry caches 的优先级(默认为 100),LinuxInsight 中有相关的解释:

At the default value of vfs_cache_pressure = 100 the kernel will attempt to reclaim dentries and inodes at a“fair”rate with respect to pagecache and swapcache reclaim. Decreasing vfs_cache_pressure causes the kernel to prefer to retain dentry and inode caches. Increasing vfs_cache_pressure beyond 100 causes the kernel to prefer to reclaim dentries and inodes.

具体的设置方法,可以参考方法 1 或者方法 2 均可。

参考资料

https://www.kernel.org/doc/Documentation/sysctl/vm.txt

http://major.io/2008/12/03/reducing-inode-and-dentry-caches-to-keep-oom-killer-at-bay/

http://linux-mm.org/Drop_Caches

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2015-08/121565p2.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计6069字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中