BLAST内存容量规划与云端资源调优 - 第4节

4、Linux 系统内存监控命令详解

说到 BLAST 内存超限,你第一件事是什么?

我个人习惯,先看看系统内存到底是怎么用的。内存监控这块,工具不少,但说实话,很多人只会敲个 free -h,然后盯着 Mem 那行发呆。这哪够啊?

今天咱们就把这些命令掰开揉碎,一个个过。你跟着我走一遍,以后遇到 BLAST 占内存的问题,心里就有谱了。

4.1 先看全局:free 命令

free 是大家最常用的。但我要问你一句:你确定你看懂了?

来,先看看输出:

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           31Gi       8.9Gi       1.2Gi       1.1Gi        21Gi        21Gi
Swap:         2.0Gi       0.0Gi       2.0Gi

很多人看到 used 是 8.9G,free 只有 1.2G,就慌了。其实没必要。注意那个 available,它才是真正能用的内存。Linux 会把空闲内存拿去做缓存(buff/cache),但应用需要时,系统会立刻回收。

我的习惯:我一般不看 free 列,直接看 available。只要 available 还有余量,BLAST 大概率不是系统层面内存不够。

我在项目中遇到过,BLAST 跑着跑着 OOM 了,free 显示还有 10G 可用。什么情况?后来才查出来,是某个进程偷偷占了大量虚拟内存。

free 关键指标速查

列名 含义 排查 BLAST 时关注点
total 物理内存总量 确认节点硬件规格,看是否满足 BLAST 数据库/任务需求
used 已用内存(含缓存) 这个值高不一定有问题
free 完全未使用的内存 偏低正常,Linux 倾向于利用空闲内存做缓存
buff/cache 用于缓存和缓冲的内存 BLAST 对大数据库频繁读写时,这部分会增大
available 实际可分配给新进程的内存 核心指标 — 如果这个值远小于 BLAST 的单任务内存需求,大概率要超限
swap 交换分区使用量 一旦 swap 被大量使用,BLAST 性能会急剧下降
注意:如果 available 很低,而 buff/cache 很高,你可以手动清理页面缓存试试:sync && echo 3 > /proc/sys/vm/drop_caches。但别在生产环境乱用,先确认没人在跑关键任务。

4.2 动态监测:vmstat 命令

free 是快照,vmstat 才是动态的。你想想看,系统内存怎么分配的?进程怎么调度的?它都能告诉你。

我最常用的是:

$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 1314560 123456 18987654    0    0   123    45  456  789 12  3 85  0  0

每条记录间隔 1 秒,共 5 次。看哪几列?

  • r (procs): 运行队列。BLAST 多线程时,这个数值如果超过 CPU 核心数太多,说明 CPU 是瓶颈。
  • si / so (swap): 交换入/出。这两个一旦不是 0,赶紧去看 BLAST 是不是吃太多内存了。
  • free: 空闲内存。如果持续下降,说明内存压力在增大。
  • us / sy (cpu): 用户态和内核态 CPU 占用。

避坑指南:我曾经有一次排查 BLAST 超限,发现 free 内存一直在降,但 process 的各项指标都正常。最后追到根上,是同一台机器上另一个人的数据库查询进程在作怪。所以别只看自己的进程。

4.3 进程级洞察:top / htop

全局看完,就得定位到具体进程。二话不说,上 top:

$ top -u blast_user -o %MEM -b -n 1

这条命令,只看 blast_user 用户的进程,按内存占用排序,输出一次。我习惯用 -b -n 1 把结果一次性打印出来,方便截图或写脚本。

在 top 里,你会看到 VIRT、RES、SHR 三列:

  • VIRT (Virtual Memory): 进程申请的虚拟内存总量。这个值通常很大,但别被吓到。BLAST 加载大数据库时,虚拟内存会飙到很高。
  • RES (Resident Memory): 实际驻留在物理内存中的部分。这才是你真正关心的内存消耗。
  • SHR (Shared Memory): 共享内存。多个 BLAST 实例加载同一个数据库时,这部分可以共享。

如果 RES 持续增长,直到接近物理内存上限,那就危险了。

我个人更喜欢 htop,界面友好,还能看树形结构:

$ htop -u blast_user

按 F6 可以选排序字段,按 MEM% 排,一目了然。

小技巧:如果系统没有 htop,可以用 top -H 查看线程级别的资源占用。BLAST 是多线程的,有时候某个线程异常,也会导致整体内存超限。

4.4 精细化:ssmem / /proc 文件系统

提到内存监控,我不能不提 smem。这工具能告诉你 USS、PSS、RSS 三个指标。

为啥重要?

你想想,两个 BLAST 实例跑同一个数据库,共享内存怎么算?RSS 会把共享部分重复计算,但 PSS (Proportional Set Size) 会按比例分摊。这才是真实的内存开销。

$ smem -t -p -u blast_user | head -20

输出示例:

  PID User     Command                         Swap      USS      PSS      RSS
12345 blast    blastn -db nt -query test.fa        0   45.6M   56.2M  102.3M
12346 blast    blastx -db nr -query test.fa        0   78.9M   89.1M  156.4M

看 USS 列,那是进程独占的内存。PSS 是分摊后的值。如果你的 BLAST 任务内存超限,但 RSS 不高,PSS 却很高,说明共享内存效率有问题。

/proc 文件系统:最底层的王者

有时候,命令不够用,就自己读 /proc:

$ cat /proc/meminfo | grep -E '^(Mem|Swap|DirectMap|Unevictable)'
MemTotal:       32670200 kB
MemFree:         1314560 kB
MemAvailable:   22345678 kB
SwapTotal:       2097152 kB
SwapFree:        2097148 kB

想看某个进程的内存映射?这样:

$ cat /proc/12345/status | grep -E '(VmRSS|VmSize|VmPeak)'
VmPeak:   1048576 kB
VmSize:    987654 kB
VmRSS:      51234 kB

VmPeak 是峰值内存,VmRSS 是当前驻留内存。如果 VmPeak 远超物理内存,说明 BLAST 曾经申请过大量内存,后来部分被换出了。

4.5 诊断实例:一次 BLAST OOM 快速定位

我记得有一次,BLAST 跑了一小时,突然挂了,日志里只有一句 "Killed"。怎么查的?

  1. 先用 dmesg | tail -20,果然发现 OOM killer 的记录:
Out of memory: Killed process 12345 (blastn) total-vm:2097152kB, anon-rss:1024128kB, file-rss:23456kB

这下确认,是被内核杀了。

  1. 然后看 OOM 前后的系统状态:
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           31Gi       29Gi       0.1Gi       1.0Gi        1.9Gi       1.2Gi

available 只剩 1.2G,而 BLAST 进程的 anon-rss 是 1GB,明显内存吃紧了。

  1. 最后追根溯源:
$ smem -p -u blast_user
  PID User     Command                         PSS      USS      RSS
12345 blast    blastn -db nt -query ...      1.0G    950M    1.1G

PSS 接近 1G,USS 也 950M。这台机器总共 32G,但运行了多个 BLAST 实例,加上其他用户进程,内存耗尽。

解决方案是什么?限制 -num_threads,或者调整数据库分块策略。

4.6 避坑指南:我帮你踩过的坑

坑1:只看 RES 不看 swap

我曾经在一次 BLAST 任务中,看到 free 显示内存足够,但 BLAST 就是跑不起来。原来是 swap 已经被用光了,系统在频繁换页,性能极度下降。命令行 free -h 要看 swap 那行。

坑2:忘记考虑共享内存

多个 BLAST 实例加载同一个数据库文件时,数据库会被映射到共享内存。你在 top 里看到的每个进程的 RSS 都包含了这部分。但系统实际物理内存占用,不等于各进程 RSS 之和。smem 的 PSS 才是最准的。

坑3:过度依赖图形工具

在无桌面环境的 HPC 节点上,htop、nmon 这些用不了。所以 free、vmstat、smem、/proc 这些纯命令行工具才是王道。我养成的习惯是,所有监控命令都用 -b 批处理模式,方便日志归档。

好了,到这,你应该对 Linux 内存监控有了底。这些命令的组合套路,就是 BLAST 内存问题的第一道防线。记住四个字:多级对比。全局指标准确,但进程级信息精确;静态看 free,动态看 vmstat;大图看 RSS,细粒度看 PSS。搭配着用,基本不会漏。

本章知识体系总览

Linux 内存监控命令体系 发现 BLAST 内存超限 全局内存:free 动态监控:vmstat 进程视角:top/htop 看 buff/cache + available 观察 si/so 换页活动 区分 VIRT/RES/SHR drop_caches 清理缓存 查看 /proc/meminfo smem 看 USS/PSS/RSS 定位问题:缓存被挤占 or 进程参数配置不合理 目标:压降 RSS / 调整 -num_threads / 优化数据库分块 提示:现场排查时,建议按 free → vmstat → top → smem 顺序逐步深入;每个命令都要结合 BLAST 日志一起看