searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

分析Linux 服务器中内存占用率持续增高问题

2023-11-01 03:43:03
350
0

一、问题描述:

       存储节点中 used 内存使用量远高于进程占用的内存,此时系统 used 内存占用了96G,used内存应约等于 /proc/meminfo 中统计的 AnonPages、SReclaimable、KernelStack及PageTables总和,计算后发现后者总和约为22G ,与 used内存差距过大,故需分析该现象出现的原因。其中AnonPages 16.66G约等于进程占用的内存(RSS)总和 17.13G。

二、结论:

       used内存占用率高,是由于ceph相关的进程ceph-osd 下的tp_osd_tp线程频繁进行getdents、stat、openat等系统调用,导致内存中缓存了很多xfs_buf。当系统内存充足时,只能通过主动执行 "echo 2 > /proc/sys/vm/drop_caches " 命令触发系统回收一直未被使用的 xfs_buf,当系统内存较低时,系统通过唤醒后台异步回收 kswapd 内核线程回收该缓存。

三、问题分析过程:

      通过内核提供的接口主动进行回收,观察系统 used 内存是否能被回收。

      系统最初 used 内存有 41G,通过 echo 2 > /proc/sys/vm/drop_caches 后,系统 used 内存从 41G 降到了 29G,因此可知系统可回收内存大部分是slab。

  • 确认 slab 中具体占用内存的位置

         跟踪 echo 2 > /proc/sys/vm/drop_caches 时触发的回收流程,发现大部分回收发生在 xfs_buftarg_shrink 函数调用中。

         因此,首先查看 xfs_buftarg_shrink 函数中回收的内存总量,在跟踪过程中,系统 used 内存从 40G 降到了 29G。

         而 xfs_buftarg_shrink 函数在该过程中大约释放了 3037466 页 4k 页面,即回收了约 11G 内存,与前面计算的系统内存减少了 11G 匹配。因此,系统 used 内存中绝大部分都是 xfs_buf。

         由上文可知,xfs_buf 占用了大量内存,因此我们需要跟踪 xfs_buf 分配的内存量是否和系统 used 内存增长量一致。在跟踪过程中,系统 used 内存从 50G 增长到了 55G,而 xfs_buf 共分配了 4.68G,故 xfs_buf 分配的内存量 与 系统 used 内存增量基本一致。

         通过上述跟踪,可以得出:系统used内存增量与xfs_buf内存使用量基本一致,主动回收内存时,系统used内存减少量与xfs_buf缓存回收量基本一致。故系统used内存持续增长是由于大量的xfs_buf缓存导致。

  • xfs_buf 分配请求的主要来源

         通过上述跟踪,可以知道 tp_osd_tp 线程一直在请求分配 xfs_buf。

         其次,跟踪xfs_buf分配过程的调用栈,发现xfs_buf分配请求集中在打开文件openat 、统计文件信息stat、读取目录getdents等过程中,主要是ceph相关的进程对文件的操作导致的used内存持续增加。

  • ceph-osd 服务分配 xfs_buf 的速度及对内存的影响

         首先跟踪关掉 ceph-osd 服务后,系统在15分钟内 xfs_buf 分配请求的数量,发现分配请求均来自于titanagent 3785880线程,其在15分钟内共请求分配了6个xfs_buf,并不能使得系统内存显著增长。

         开启ceph-osd服务后,统计发现系统在15分钟内分配了 82554 个xfs_buf,系统内存也从 21G增长到了 25G。

         综上,ceph-osd服务开启后,xfs_buf分配速度从原来的15分钟内分配6个提升到了82554个,系统内存使用量显著增多。

4xfs_buf回收机制

         查看代码发现 xfs_buf 最终通过调用 xfs_buf_rele 函数来释放缓存的 xfs_buf,其通过判断 xfs_buf 的引用计数是否为 0 来决定是否直接回收内存,如果引用计数为 0,则直接回收内存,反之,则将 xfs_buf 放回到xfs lru 链表中,等回收流程被触发时再被回收。

         xfs_buf缓存回收有以下四种路径:

(1)xfs_buf映射磁盘文件时,磁盘文件丢失或内存不足,直接回收 xfs_buf;

(2) xfs log 已经回写到磁盘了,此时缓存 log 的xfs_buf可直接被回收;

(3)系统空闲内存充足时,用户通过“echo 2 > /proc/sys/vm/drop_caches”方式主动触发回收流程;

(4)系统空闲内存不足时,内核后台异步回收线程kswapd被唤醒,回收xfs_buf对应的缓存。如下所示,系统空闲内存只有3.6G 时,内核线程 kswapd 主动进行内存回收。 

       当tp_osd_tp 线程执行getdents、stat、openat等系统调用时,xfs_buf 被成功映射相应的内容后,其引用计数大于0,故被放入xfs lru链表中,等待上述回收路径中的(3)或者(4)被触发时,方能被回收释放内存。

0条评论
0 / 1000
GuoJin
7文章数
0粉丝数
GuoJin
7 文章 | 0 粉丝
原创

分析Linux 服务器中内存占用率持续增高问题

2023-11-01 03:43:03
350
0

一、问题描述:

       存储节点中 used 内存使用量远高于进程占用的内存,此时系统 used 内存占用了96G,used内存应约等于 /proc/meminfo 中统计的 AnonPages、SReclaimable、KernelStack及PageTables总和,计算后发现后者总和约为22G ,与 used内存差距过大,故需分析该现象出现的原因。其中AnonPages 16.66G约等于进程占用的内存(RSS)总和 17.13G。

二、结论:

       used内存占用率高,是由于ceph相关的进程ceph-osd 下的tp_osd_tp线程频繁进行getdents、stat、openat等系统调用,导致内存中缓存了很多xfs_buf。当系统内存充足时,只能通过主动执行 "echo 2 > /proc/sys/vm/drop_caches " 命令触发系统回收一直未被使用的 xfs_buf,当系统内存较低时,系统通过唤醒后台异步回收 kswapd 内核线程回收该缓存。

三、问题分析过程:

      通过内核提供的接口主动进行回收,观察系统 used 内存是否能被回收。

      系统最初 used 内存有 41G,通过 echo 2 > /proc/sys/vm/drop_caches 后,系统 used 内存从 41G 降到了 29G,因此可知系统可回收内存大部分是slab。

  • 确认 slab 中具体占用内存的位置

         跟踪 echo 2 > /proc/sys/vm/drop_caches 时触发的回收流程,发现大部分回收发生在 xfs_buftarg_shrink 函数调用中。

         因此,首先查看 xfs_buftarg_shrink 函数中回收的内存总量,在跟踪过程中,系统 used 内存从 40G 降到了 29G。

         而 xfs_buftarg_shrink 函数在该过程中大约释放了 3037466 页 4k 页面,即回收了约 11G 内存,与前面计算的系统内存减少了 11G 匹配。因此,系统 used 内存中绝大部分都是 xfs_buf。

         由上文可知,xfs_buf 占用了大量内存,因此我们需要跟踪 xfs_buf 分配的内存量是否和系统 used 内存增长量一致。在跟踪过程中,系统 used 内存从 50G 增长到了 55G,而 xfs_buf 共分配了 4.68G,故 xfs_buf 分配的内存量 与 系统 used 内存增量基本一致。

         通过上述跟踪,可以得出:系统used内存增量与xfs_buf内存使用量基本一致,主动回收内存时,系统used内存减少量与xfs_buf缓存回收量基本一致。故系统used内存持续增长是由于大量的xfs_buf缓存导致。

  • xfs_buf 分配请求的主要来源

         通过上述跟踪,可以知道 tp_osd_tp 线程一直在请求分配 xfs_buf。

         其次,跟踪xfs_buf分配过程的调用栈,发现xfs_buf分配请求集中在打开文件openat 、统计文件信息stat、读取目录getdents等过程中,主要是ceph相关的进程对文件的操作导致的used内存持续增加。

  • ceph-osd 服务分配 xfs_buf 的速度及对内存的影响

         首先跟踪关掉 ceph-osd 服务后,系统在15分钟内 xfs_buf 分配请求的数量,发现分配请求均来自于titanagent 3785880线程,其在15分钟内共请求分配了6个xfs_buf,并不能使得系统内存显著增长。

         开启ceph-osd服务后,统计发现系统在15分钟内分配了 82554 个xfs_buf,系统内存也从 21G增长到了 25G。

         综上,ceph-osd服务开启后,xfs_buf分配速度从原来的15分钟内分配6个提升到了82554个,系统内存使用量显著增多。

4xfs_buf回收机制

         查看代码发现 xfs_buf 最终通过调用 xfs_buf_rele 函数来释放缓存的 xfs_buf,其通过判断 xfs_buf 的引用计数是否为 0 来决定是否直接回收内存,如果引用计数为 0,则直接回收内存,反之,则将 xfs_buf 放回到xfs lru 链表中,等回收流程被触发时再被回收。

         xfs_buf缓存回收有以下四种路径:

(1)xfs_buf映射磁盘文件时,磁盘文件丢失或内存不足,直接回收 xfs_buf;

(2) xfs log 已经回写到磁盘了,此时缓存 log 的xfs_buf可直接被回收;

(3)系统空闲内存充足时,用户通过“echo 2 > /proc/sys/vm/drop_caches”方式主动触发回收流程;

(4)系统空闲内存不足时,内核后台异步回收线程kswapd被唤醒,回收xfs_buf对应的缓存。如下所示,系统空闲内存只有3.6G 时,内核线程 kswapd 主动进行内存回收。 

       当tp_osd_tp 线程执行getdents、stat、openat等系统调用时,xfs_buf 被成功映射相应的内容后,其引用计数大于0,故被放入xfs lru链表中,等待上述回收路径中的(3)或者(4)被触发时,方能被回收释放内存。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
1
0