[故障排查] NFS 存储集群卡顿的完整排查记录:谁在深夜疯狂读写?
前言
在维护 HPC(高性能计算)集群时,我们最怕遇到的情况之一就是:存储节点卡顿。
现象通常很典型:所有挂载了 NFS 的计算节点 ls 命令变慢,SSH 登录管理节点卡顿,甚至集群监控报警。本文记录了一次真实的排查过程:从磁盘 I/O 异常出发,通过网络流量分析定位源头,最终发现是一个意想不到的"桌面组件"搞垮了整个存储服务。
同时,本文将详细介绍排查过程中用到的 Linux 性能分析工具,包括所有常用参数、使用技巧和实战场景,希望能成为运维同行的实战参考手册。
第一阶段:案发现场与初步诊断
现象
管理节点(也是 NFS Server)响应极慢,SSH 输入命令有明显延迟。用户反馈计算节点上访问 /home 目录时 ls 命令卡住不动。
工具 1:iostat ------ 宏观查看磁盘健康度
首先,我们需要确认是不是磁盘撑不住了。iostat 是最经典的 I/O 性能工具。
基础用法
bash
# -x 显示扩展统计信息
# 1 每秒刷新一次
iostat -x 1
现场数据(截取)
text
Device r/s rkB/s r_await w/s wkB/s w_await %util
sdb 191.00 6984.0 31.68 45.00 1470.0 3.67 92.80
数据解读
%util(92.80%): 红色警报!这块盘几乎 100% 的时间都在工作,没有空闲。rkB/s(6984.0) : 只有约 6.8 MB/s。利用率满了,吞吐量却这么低?这说明是在做大量的随机小 I/O。r_await(31.68 ms): 读请求平均等待时间超过 30ms。对于磁盘来说,超过 10ms 就会感觉到卡顿,30ms 说明磁头已经在疯狂跳动了。r/s(191): 每秒 191 次读操作,这个数字配合低吞吐量,证实了是小文件随机读的模式。
初步结论
磁盘 sdb 正遭受大量随机读取攻击,导致 I/O 队列阻塞。这是典型的"IOPS 瓶颈"而非"带宽瓶颈"。
第二阶段:寻找本地嫌疑人
工具 2:iotop ------ 锁定读写进程
知道磁盘忙,但谁在忙?iotop 是类似 top 的工具,专门用来抓 I/O 大户。
基础用法
bash
# -o 只显示有 I/O 行为的进程
# -P 只显示进程,不显示线程(让视图更清爽)
# -a 累积模式(Accumulated),显示从运行命令开始的总量,而不是瞬时速度
sudo iotop -oPa
现场发现
nfsd(多个进程): 读写量很大。这符合预期,因为这是一台 NFS Server,压力肯定来自网络端的客户端。qaxsafed(天擎杀毒) : 关键发现! 它的读取量高达 4GB(累积),远超其他进程。liyue(用户) : 正在运行tar -czf DLDock.tar.gz ../home/liyue/DLDock,累积读取约 800MB。
深度分析
虽然 nfsd 在读写,但杀毒软件 qaxsafed 的读取量异常高。这通常意味着:NFS 每读取一个文件,杀毒软件就拦截下来扫描一次。如果是海量小文件场景(如深度学习数据集),这会造成 IOPS 的双倍甚至多倍放大。
第三阶段:追踪网络流量
既然 nfsd 很忙,说明是外部计算节点在请求数据。我们需要找出是哪台机器在疯狂请求。
工具 3:iftop ------ 实时流量监控
iftop 能直观地展示网络连接的"源"和"目"以及流量大小,是网络排查的第一利器。
基础用法
bash
# -n 不解析域名(直接显示IP,速度快)
# -P 显示端口
sudo iftop -n -P
使用 -T 参数:累积流量统计(重点!)
在实际排查中,我们使用了 -T 参数来切换为累积流量统计模式,这样可以看到从运行命令开始至今,每个连接的总传输量:
bash
sudo iftop -n -P -T
或者 ,在 iftop 运行后,直接按键盘 T 键(注意是大写 T),也可以切换为累积模式。
累积模式的价值
在高频、短连接的场景下(如 NFS),瞬时流量可能忽高忽低,难以判断"谁是大户"。累积模式能清楚地显示从监控开始到现在,哪个 IP 总共传输了最多的数据。
现场数据(累积模式截图分析)
界面右侧的三列数值分别代表:
- 第一列(1.86s): 最近 2 秒的累积流量
- 第二列(3.73s): 最近 10 秒的累积流量
- 第三列(5.59s): 最近 40 秒的累积流量
我们观察到:
cn04(183.169.15.X) : 累积发送了约 2.76GB ,瞬时速率约 34 Mb/scn06(183.169.15.Y) : 累积发送了约 2.28GB ,瞬时速率约 22 Mb/scn03(183.169.15.Z) : 累积发送了约 897 MB ,瞬时速率约 20 Mb/s
疑点: 30Mb/s 的流量对于千兆/万兆网卡来说微不足道,为什么会卡?
解答: 结合 iostat 的低吞吐、高 %util,这再次印证了海量小文件的推测。几万个 1KB 的文件传输,带宽占用不大,但能把磁盘 IOPS 打满。
现场决策
既然 cn04 和 cn06 流量最大,我们决定先去 cn06 抓现行(因为用户反馈 cn06 上并没有正在运行的 Slurm 作业,这很可疑)。
第四阶段:计算节点抓现行
锁定了 cn06 节点后,我们发现该节点上并没有正在运行的 Slurm 作业(squeue -w cn06 显示为空),那流量是谁跑的?
工具 4:lsof ------ 谁在动我的文件?
lsof (List Open Files) 可以列出当前系统打开的所有文件。Linux 下一切皆文件,所以它能查看进程打开的普通文件、网络套接字、设备文件等。
查看谁在访问 NFS 挂载点
bash
# -n 不解析主机名(加快速度)
# grep 过滤出包含管理节点 IP 的行
lsof -n | grep 183.169.15.16
现场发现(部分截取)
text
tracker-m 1643873 yangsen cwd DIR 0,60 4096 636059839 /public/home/yangsen (183.169.15.16:/public)
tracker-m 1643873 yangsen 9ur REG 0,60 2859008 680109301 /public/home/yangsen/.cache/tracker3/files/meta.db
tracker-m 3110329 wanglei cwd DIR 0,60 4096 636059734 /public/home/wanglei (183.169.15.16:/public)
tracker-m 3110342 xinqian cwd DIR 0,60 4096 674699443 /public/home/xinqian (183.169.15.16:/public)
pipewire 637664 xinqian cwd DIR 0,60 4096 674699443 /public/home/xinqian (183.169.15.16:/public)
gvfsd 637729 xinqian cwd DIR 0,60 4096 674699443 /public/home/xinqian (183.169.15.16:/public)
关键线索: 大量的 tracker-miner-fs-3、pipewire、gvfsd 等进程正在访问 /public 下的用户主目录。
工具 5:fuser ------ 快速定位文件使用者
fuser 比 lsof 更轻量,专门用于快速检查文件或目录被谁占用。
查看谁在使用挂载点
bash
# -u 显示用户名
# -v 详细模式
fuser -uv /public
现场输出(部分)
text
Cannot stat file /proc/1643873/fd/10: Stale file handle
Cannot stat file /proc/1643873/fd/11: Stale file handle
...
USER PID ACCESS COMMAND
/public: root kernel mount (root)/public
Stale file handle 错误: 这是 NFS 特有的错误,意味着文件句柄失效了。通常是因为:
- NFS 服务器过载,无法响应
- 文件已经被删除,但进程还持有句柄
这侧面印证了 NFS 服务器此刻的痛苦状态。
破案时刻
综合 lsof 的输出,真凶浮出水面:GNOME Tracker
这是 Linux 桌面环境(GNOME)自带的文件索引服务。当用户通过 VNC 或 X11 Forwarding 登录图形界面时,Tracker 会自动启动,并试图为用户目录下的所有文件建立索引(类似 Windows 的索引服务)。
灾难场景还原:
- 用户(
yangsen,likun,wanglei,xinqian)通过 VNC 登录到cn06的桌面环境。 - GNOME 桌面启动,
tracker-miner-fs-3后台服务自动运行。 - Tracker 发现用户主目录(
/public/home/username)有新文件,开始全盘扫描。 - 由于
/public是 NFS 挂载的,每次扫描文件属性(stat)都是一次网络请求。 - 如果目录下有几百万个小文件(深度学习常态),NFS 服务器瞬间被几百万个
stat请求淹没。 - 加上管理节点上的杀毒软件
qaxsafed对每个被访问的文件进行拦截扫描,形成了"双重打击"。
第五阶段:解决方案
1. 紧急止血
在计算节点(如 cn06)上杀死相关进程:
bash
killall -9 tracker-miner-fs-3 tracker-store tracker-extract-3
执行后,回到管理节点查看 iostat,sdb 的 %util 从 92% 瞬间降至 15%,NFS 服务恢复正常。
2. 根除病灶
计算节点通常不需要文件索引功能,甚至不需要图形界面。
方案 A:禁用图形界面(推荐)
将计算节点默认启动级别设为多用户文本模式:
bash
# 设置默认启动目标
sudo systemctl set-default multi-user.target
# 立即切换(不重启)
sudo systemctl isolate multi-user.target
批量操作所有计算节点:
bash
# 假设节点命名为 cn01-cn10
for i in {01..10}; do
echo "Processing cn$i..."
ssh cn$i "sudo systemctl set-default multi-user.target"
done
方案 B:暴力移除执行权限(保留桌面时使用)
如果必须保留桌面,可以移除 Tracker 二进制文件的执行权限,防止复活:
bash
#!/bin/bash
# 文件名: disable_tracker.sh
# 1. 杀掉当前进程
pkill -9 -f tracker-miner
pkill -9 -f tracker-store
pkill -9 -f tracker-extract
# 2. 移除执行权限(Ubuntu/Debian)
if [ -d "/usr/libexec" ]; then
chmod -x /usr/libexec/tracker-miner-fs-3 2>/dev/null
chmod -x /usr/libexec/tracker-store 2>/dev/null
chmod -x /usr/libexec/tracker-extract-3 2>/dev/null
chmod -x /usr/libexec/tracker-miner-apps 2>/dev/null
fi
# 3. 移除自动启动配置
mkdir -p /etc/xdg/autostart/disabled
mv /etc/xdg/autostart/tracker-*.desktop /etc/xdg/autostart/disabled/ 2>/dev/null
echo "Tracker 已被禁用。"
批量执行:
bash
for i in {01..10}; do
ssh cn$i "sudo bash -s" < disable_tracker.sh
done
附录:Linux 性能分析工具箱详解
在本次排查中,我们用到了一系列工具。以下是它们的详细用法速查,包含所有常用参数和实战技巧。
1. iostat - I/O 统计工具
所属包 : sysstat
安装 : sudo apt install sysstat (Debian/Ubuntu) 或 sudo yum install sysstat (RHEL/CentOS)
常用参数表
| 参数 | 说明 | 使用场景 |
|---|---|---|
-x |
显示扩展统计信息(包含 await 等关键指标) | 必加,不加的话看不到等待时间 |
-k |
以 KB 为单位显示(默认是 block) | 提高可读性 |
-m |
以 MB 为单位显示 | 高吞吐场景下更直观 |
-d |
只显示磁盘统计,不显示 CPU | 专注 I/O 问题时使用 |
-c |
只显示 CPU 统计 | 结合磁盘看 I/O wait |
-p <device> |
显示指定设备及其分区 | 例如 iostat -x -p sda |
<interval> |
刷新间隔(秒) | 例如 iostat 1 每秒刷新 |
<count> |
刷新次数 | 例如 iostat 1 10 每秒刷新,共 10 次 |
实战命令组合
bash
# 1. 每秒刷新,显示扩展信息(最常用)
iostat -x 1
# 2. 只看磁盘,不看 CPU
iostat -dx 1
# 3. 以 MB 为单位,方便大流量时查看
iostat -xm 1
# 4. 查看特定磁盘的所有分区
iostat -xp sdb 1
# 5. 记录 60 秒的数据并保存
iostat -x 1 60 > iostat_$(date +%Y%m%d_%H%M%S).log
关键指标解读
| 指标 | 含义 | 正常值参考 | 异常判断 |
|---|---|---|---|
r/s, w/s |
每秒读/写操作次数(IOPS) | 取决于磁盘类型 | SSD 可达数万,机械盘几百 |
rkB/s, wkB/s |
每秒读/写吞吐量 | - | 对比磁盘标称性能 |
r_await |
读请求平均等待时间(ms) | SSD < 1ms HDD < 10ms | > 20ms 用户可感知卡顿 |
w_await |
写请求平均等待时间(ms) | 同上 | 同上 |
svctm |
(已废弃)平均服务时间 | - | 新版本已不显示 |
%util |
设备利用率 | < 80% | > 90% 表示磁盘饱和 |
关键经验:
%util接近 100% 但await很低(< 5ms):可能是顺序读写,磁盘虽忙但不卡。%util不高(50%)但await很高(> 50ms):磁盘硬件可能有问题,或者队列调度策略不佳。await是判断用户体验的核心指标 ,比%util更重要。
2. iotop - I/O 进程监控工具
安装 : sudo apt install iotop (Debian/Ubuntu) 或 sudo yum install iotop (RHEL/CentOS)
常用参数表
| 参数 | 说明 | 推荐度 |
|---|---|---|
-o, --only |
仅显示正在产生 I/O 的进程 | ⭐⭐⭐⭐⭐ 必加 |
-b, --batch |
批处理模式(适合输出到文件) | ⭐⭐⭐⭐ |
-n <NUM> |
批处理模式下的迭代次数 | ⭐⭐⭐ |
-d <SEC> |
刷新延迟(秒) | ⭐⭐⭐ |
-p <PID> |
只监控特定进程 | ⭐⭐⭐⭐ |
-u <USER> |
只监控特定用户 | ⭐⭐⭐⭐ |
-P, --processes |
只显示进程,不显示线程 | ⭐⭐⭐⭐⭐ 必加 |
-a, --accumulated |
累积模式(显示总量) | ⭐⭐⭐⭐⭐ 抓慢性病必备 |
-k, --kilobytes |
以 KB 显示 | ⭐⭐⭐ |
-t, --time |
显示时间戳 | ⭐⭐⭐ |
-q, --quiet |
静默模式(减少输出) | ⭐⭐ |
实战命令组合
bash
# 1. 最常用组合:只看活跃进程,不显示线程,累积模式
sudo iotop -oPa
# 2. 监控特定用户的 I/O(排查某个同学的任务)
sudo iotop -u liyue -oPa
# 3. 监控特定进程
sudo iotop -p 123456 -oPa
# 4. 批处理模式,记录 60 次快照,每次间隔 1 秒
sudo iotop -boa -d 1 -n 60 > iotop_$(date +%Y%m%d_%H%M%S).log
# 5. 只看读写超过 1MB/s 的进程(需配合 -b 模式后用 awk 过滤)
sudo iotop -oP -d 1
交互快捷键(运行中按键)
| 快捷键 | 功能 |
|---|---|
a |
切换累积/瞬时模式(Accumulated / Current) |
o |
切换显示全部/仅活跃进程 |
p |
切换显示进程/线程 |
左右箭头 |
切换排序列 |
r |
反向排序 |
q |
退出 |
关键经验
- 累积模式(
-a)的价值:很多进程是"间歇性读写",瞬时速度不高,但累积量惊人。例如每秒读 100KB,但连续读 3 小时,累积就是 1GB+。累积模式能抓到这种"慢性毒药"。 - 配合
watch使用 :watch -n 1 "sudo iotop -oP -b -n 1 | head -20"可以制作简易监控面板。
3. iftop - 网络流量监控工具
安装 : sudo apt install iftop (Debian/Ubuntu) 或 sudo yum install iftop (RHEL/CentOS)
常用参数表
| 参数 | 说明 | 推荐度 |
|---|---|---|
-n |
不解析主机名(显示 IP) | ⭐⭐⭐⭐⭐ 必加 |
-N |
不解析端口名(显示数字端口) | ⭐⭐⭐⭐ |
-P |
显示端口号 | ⭐⭐⭐⭐⭐ 排查服务必备 |
-i <interface> |
指定网络接口 | ⭐⭐⭐⭐⭐ |
-F <network/mask> |
过滤特定网段 | ⭐⭐⭐⭐ |
-f <filter> |
BPF 过滤表达式(类似 tcpdump) | ⭐⭐⭐⭐ |
-B |
以字节显示(而非 bits) | ⭐⭐⭐ |
-m <limit> |
设置刻度上限 | ⭐⭐ |
-t |
文本模式(无 ncurses 界面) | ⭐⭐⭐⭐ |
-T |
显示累积流量统计 | ⭐⭐⭐⭐⭐ 本案关键 |
-L <limit> |
设置显示行数 | ⭐⭐⭐ |
实战命令组合
bash
# 1. 最常用组合:不解析域名,显示端口
sudo iftop -n -P
# 2. 累积流量统计模式(本次排查的核心)
sudo iftop -n -P -T
# 3. 指定网卡(多网卡服务器必须指定)
sudo iftop -i eth0 -n -P
# 4. 只监控特定网段(例如只看内网流量)
sudo iftop -n -P -F 192.168.1.0/24
# 5. 只监控 NFS 流量(端口 2049)
sudo iftop -n -P -f "port 2049"
# 6. 文本模式输出(适合 SSH 环境差的情况)
sudo iftop -t -s 5 -n -P
# 7. 以字节(Bytes)而非比特(bits)显示
sudo iftop -n -P -B
交互快捷键(运行中按键)
| 快捷键 | 功能 | 重要度 |
|---|---|---|
T (大写) |
切换显示累积流量/瞬时速率 | ⭐⭐⭐⭐⭐ |
t (小写) |
切换显示方式(单向/双向/总和) | ⭐⭐⭐⭐ |
n |
切换 DNS 解析 | ⭐⭐⭐ |
N |
切换端口解析 | ⭐⭐⭐ |
s |
切换源主机显示 | ⭐⭐⭐ |
d |
切换目标主机显示 | ⭐⭐⭐ |
p |
切换是否显示端口 | ⭐⭐⭐⭐ |
b |
切换显示条形图 | ⭐⭐ |
B |
切换 Bytes/bits 显示 | ⭐⭐⭐ |
< / > |
按源/目标排序 | ⭐⭐⭐⭐ |
? |
显示帮助 | ⭐⭐⭐⭐⭐ |
q |
退出 | - |
界面详解
text
ln00 => cn04 1.42GB 34.6Mb 48.9Mb 39.0Mb
<= 29.8MB 623Kb 822Kb 693Kb
- 第一行 :
ln00发送给cn04的流量 - 第二行 :
ln00从cn04接收的流量 - 右侧三列: 分别是 2秒、10秒、40秒 的平均速率
- 最左侧(累积模式): 从运行开始到现在的总流量
关键经验:累积模式(-T)的实战价值
在本次排查中,累积模式是破案的关键。原因:
- NFS 流量特征是高频小包:瞬时速率可能只有 10-30 Mb/s,不容易引起注意。
- 但持续时间长:如果持续 10 分钟,累积流量就可能达到 GB 级别。
- 累积模式能清晰区分"正常用户"和"异常用户" :
- 正常用户:累积 100MB(偶尔访问)
- 异常用户:累积 2.7GB(持续扫描文件)
操作技巧: 运行 iftop 后,先按一次 T 切换到累积模式,观察 2-3 分钟,就能清楚看到谁是流量大户。
4. lsof - 列出打开的文件
系统自带工具,无需安装。
常用参数表
| 参数 | 说明 | 使用场景 |
|---|---|---|
-p <PID> |
列出指定进程打开的文件 | 排查进程在读写什么 |
-u <user> |
列出指定用户打开的文件 | 排查用户行为 |
-c <command> |
列出指定命令名打开的文件 | 例如 -c python |
-i [protocol][@host][:port] |
列出网络连接 | 例如 -i :22 看 SSH |
-n |
不解析主机名 | ⭐⭐⭐⭐⭐ 加速必备 |
-P |
不解析端口名 | ⭐⭐⭐⭐ |
+D <dir> |
递归列出目录下被打开的文件 | 查挂载点占用 |
-t |
仅输出 PID(配合 kill 使用) | ⭐⭐⭐⭐⭐ |
-r <seconds> |
循环模式,每 N 秒刷新 | 持续监控 |
实战命令组合
bash
# 1. 查看指定进程打开了哪些文件
lsof -p 12345
# 2. 查看谁在使用特定文件
lsof /var/log/syslog
# 3. 查看谁连着 NFS 服务器(假设 NFS 服务器 IP 是 192.168.1.100)
lsof -n | grep 192.168.1.100
# 4. 查看谁占用了挂载点(比 fuser 更详细)
lsof +D /mnt/nfs
# 5. 查看所有 NFS 相关的网络连接
lsof -n -i :2049
# 6. 查看特定用户的所有网络连接
lsof -u www-data -i
# 7. 杀掉所有占用某个文件的进程(危险操作!)
kill -9 $(lsof -t /path/to/file)
# 8. 持续监控某个进程的文件打开情况(每 2 秒刷新)
lsof -r 2 -p 12345
输出字段解读
text
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python 1234 alice 3r REG 8,1 1048576 123456 /data/file.txt
- COMMAND: 进程名(截断至 9 字符)
- PID: 进程 ID
- USER: 所属用户
- FD : 文件描述符
- 数字 + 模式(
r读,w写,u读写) cwd= 当前工作目录txt= 程序代码mem= 内存映射文件
- 数字 + 模式(
- TYPE : 类型
REG= 普通文件DIR= 目录CHR= 字符设备IPv4/IPv6= 网络套接字
- NAME: 文件路径或网络连接信息
关键经验
-n参数必加 :不加的话,lsof会尝试反向解析每个 IP,如果 DNS 服务慢,命令会卡很久。- 配合
grep使用 :lsof输出巨大,必须结合grep过滤。 - 查 NFS 卡顿时的黄金命令 :
lsof -n | grep <nfs_server_ip>
5. fuser - 快速查找文件使用者
系统自带工具 ,比 lsof 更轻量,专注于"谁在用这个文件/目录"。
常用参数表
| 参数 | 说明 | 危险度 |
|---|---|---|
-u |
显示用户名 | - |
-v |
详细模式(Verbose) | - |
-m |
显示挂载点上的所有进程 | - |
-k |
杀掉所有使用该文件的进程 | ⚠️ 高危 |
-i |
杀进程前询问(配合 -k 使用) |
推荐 |
-signal |
指定发送的信号(默认 SIGKILL) | - |
实战命令组合
bash
# 1. 查看谁在使用挂载点(最常用)
fuser -uv /mnt/nfs
# 2. 查看谁在使用特定文件
fuser -uv /var/log/syslog
# 3. 杀掉所有占用挂载点的进程(危险!卸载磁盘前使用)
fuser -km /mnt/nfs
# 4. 杀进程前询问确认
fuser -kim /mnt/nfs
# 5. 发送 SIGTERM 而非 SIGKILL(更温柔)
fuser -k -TERM /mnt/nfs
# 6. 查看网络端口占用(也可以用 fuser)
fuser -n tcp 80
ACCESS 类型解读
当使用 -v 参数时,会显示 ACCESS 列:
| 符号 | 含义 |
|---|---|
c |
Current directory (当前工作目录) |
e |
Executable (可执行文件) |
f |
Open file (打开的普通文件) |
F |
Open file for writing (写模式打开) |
r |
Root directory (根目录) |
m |
Memory-mapped file (内存映射文件) |
关键经验
fuservslsof:fuser:速度快,输出简洁,适合快速检查。lsof:功能强大,输出详细,适合深度分析。
- 卸载磁盘前必用 :
umount /mnt提示 "device is busy" 时,用fuser -uv /mnt找出谁在占用,然后fuser -km /mnt强制杀掉。 Stale file handle错误:这是 NFS 特有问题,表示文件句柄失效。通常需要重启客户端或服务端的 NFS 服务才能彻底清除。
6. netstat & ss - 网络连接查看工具
netstat 是经典工具,但在新系统中被 ss 取代(速度更快)。
netstat 常用参数
| 参数 | 说明 |
|---|---|
-a |
显示所有连接(包括监听) |
-n |
不解析主机名和端口名 |
-t |
仅显示 TCP 连接 |
-u |
仅显示 UDP 连接 |
-p |
显示进程信息(需 root) |
-l |
仅显示监听端口 |
-c |
连续显示(刷新) |
ss 常用参数(推荐)
| 参数 | 说明 |
|---|---|
-t |
TCP 连接 |
-u |
UDP 连接 |
-a |
所有连接 |
-l |
监听端口 |
-n |
数字格式 |
-p |
显示进程 |
-s |
统计摘要 |
实战命令组合
bash
# 1. 查看谁连着 NFS 端口(2049)
netstat -anp | grep :2049
ss -anp | grep :2049
# 2. 统计每个 IP 的连接数(找出连接大户)
netstat -an | grep :2049 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr
# 3. 查看 ESTABLISHED 状态的连接
ss -tn state established
# 4. 查看所有监听端口
ss -tlnp
# 5. 持续监控连接数变化
watch -n 1 "ss -s"
在 NFS 排查中的应用
bash
# 找出连接 NFS 服务器最多的 IP(揪出吸血鬼)
netstat -an | grep :2049 | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10
输出示例:
text
50 192.168.1.101 # 这个 IP 有 50 个连接,嫌疑很大
5 192.168.1.102
2 192.168.1.103
7. pidstat - 进程统计工具
属于 sysstat 包,是 top 和 iostat 的结合体。
常用参数表
| 参数 | 说明 |
|---|---|
-d |
显示 I/O 统计 |
-r |
显示内存统计 |
-u |
显示 CPU 统计 |
-w |
显示上下文切换 |
-t |
显示线程 |
-p <PID> |
指定进程 |
-h |
水平显示(适合宽屏) |
实战命令
bash
# 1. 查看所有进程的 I/O 统计(替代 iotop)
pidstat -d 1
# 2. 查看特定进程的 I/O
pidstat -d -p 12345 1
# 3. 查看内存使用
pidstat -r 1
# 4. 查看 CPU 使用
pidstat -u 1
# 5. 综合监控(I/O + CPU + 内存)
pidstat -dur 1
优势
- 无需 root 权限(不像
iotop) - 可以记录历史数据(配合
sar工具) - 输出格式规范,易于解析(适合写监控脚本)
8. squeue & scontrol - Slurm 集群管理工具
HPC 集群管理员的基本功。
squeue 常用参数
| 参数 | 说明 |
|---|---|
-w <node> |
查看特定节点的作业 |
-u <user> |
查看特定用户的作业 |
-j <jobid> |
查看特定作业 |
-t <state> |
按状态过滤(R=运行, PD=排队) |
--start |
显示预计开始时间 |
-o <format> |
自定义输出格式 |
scontrol 常用命令
bash
# 1. 查看作业详情(包括脚本路径)
scontrol show job <jobid>
# 2. 查看节点状态
scontrol show node cn06
# 3. 暂停作业
scontrol suspend <jobid>
# 4. 恢复作业
scontrol resume <jobid>
# 5. 修改作业时间限制
scontrol update jobid=<jobid> TimeLimit=48:00:00
实战场景
bash
# 找出 cn06 上所有用户的作业
squeue -w cn06 -o "%.18i %.9P %.8j %.8u %.2t %.10M %.6D %R"
# 找出占用内存最多的作业
squeue -o "%.18i %.9P %.8j %.8u %.10M %.10l %.6D %.6C %.10m %R" --sort=-m
9. strace - 系统调用跟踪(高级调试)
用于跟踪进程的系统调用,排查"卡在哪个系统调用"。
常用场景
bash
# 1. 跟踪正在运行的进程
strace -p 12345
# 2. 只看文件操作(open, read, write)
strace -e trace=file -p 12345
# 3. 只看网络操作
strace -e trace=network -p 12345
# 4. 统计每种系统调用的耗时
strace -c -p 12345
# 5. 跟踪新启动的进程
strace -o output.txt python train.py
在 NFS 排查中的应用
如果怀疑某个进程卡在 NFS 操作上:
bash
strace -e trace=file,desc -p <PID>
如果看到大量的 stat(), open(), getdents() 调用阻塞,就能证实是 NFS 响应慢导致的。
10. dstat - 多合一监控工具(推荐新手)
集成了 iostat, vmstat, ifstat 的功能,界面友好。
安装与使用
bash
# 安装
sudo apt install dstat
# 使用(最常用)
dstat -cdngy --disk-util --top-io --top-bio
参数说明
-c: CPU 使用率-d: 磁盘 I/O-n: 网络流量-g: 分页统计-y: 系统统计--disk-util: 磁盘利用率--top-io: 最耗 I/O 的进程--top-bio: 最耗 block I/O 的进程
总结与最佳实践
问题根源分析
这次故障的根本原因是:桌面环境的文件索引服务(Tracker)与 HPC 环境的海量小文件场景不兼容。
- Tracker 设计初衷 :为桌面用户提供快速文件搜索,扫描
~/Documents这种几千个文件的目录。 - HPC 环境现实:用户目录下有几百万个小文件(深度学习数据集)。
- 灾难性交互 :Tracker 发起几百万次
stat()调用 → NFS 服务器过载 → 杀毒软件雪上加霜(每个文件扫描一遍)。
运维建议
1. 计算节点配置规范
- 强制禁用桌面索引服务 :
chmod -x /usr/libexec/tracker-* - 尽量使用文本模式 :
systemctl set-default multi-user.target - 如需桌面,使用轻量级环境:XFCE 或 LXDE,不要用 GNOME/KDE。
2. NFS 服务器优化
-
将数据目录加入杀毒软件白名单:避免实时扫描。
-
使用 NFS v4.2:支持更好的并发和缓存。
-
调整内核参数 :
bash# 增加 NFS 线程数 echo 128 > /proc/fs/nfsd/threads # 增加网络缓冲区 sysctl -w net.core.rmem_max=134217728 sysctl -w net.core.wmem_max=134217728
3. 用户教育
- 数据集预处理:将小文件打包成 tar 或转换为 HDF5/TFRecord。
- 使用计算节点本地盘 :将数据集拷贝到
/tmp或/local,训练结束后再传回 NFS。
排查方法论总结
遇到类似问题时,推荐的排查顺序:
1. iostat -x 1 → 确认是磁盘问题
2. iotop -oPa → 找出本地读写进程
3. iftop -n -P -T → 找出网络流量源头(-T 累积模式关键!)
4. ssh <client_node> → 登录客户端
5. lsof -n | grep <server_ip> → 找出具体进程
6. strace -e trace=file -p <PID> → 确认系统调用阻塞点
7. kill / 修复配置 → 解决问题
监控脚本示例
最后,这里提供一个简易的监控脚本,可以定期检查并告警:
bash
#!/bin/bash
# 文件名: nfs_monitor.sh
DISK="sdb"
THRESHOLD_UTIL=90
THRESHOLD_AWAIT=20
UTIL=$(iostat -x $DISK 1 2 | tail -1 | awk '{print $14}' | cut -d. -f1)
AWAIT=$(iostat -x $DISK 1 2 | tail -1 | awk '{print $10}' | cut -d. -f1)
if [ "$UTIL" -gt "$THRESHOLD_UTIL" ] && [ "$AWAIT" -gt "$THRESHOLD_AWAIT" ]; then
echo "警告:磁盘 $DISK 负载过高!"
echo "利用率: ${UTIL}%, 等待时间: ${AWAIT}ms"
# 记录当前 I/O 大户
iotop -oPab -n 1 > /tmp/iotop_$(date +%Y%m%d_%H%M%S).log
# 发送邮件告警(需配置 mail 命令)
# echo "详见附件" | mail -s "NFS 服务器告警" -a /tmp/iotop_*.log admin@example.com
fi
添加到 cron 定时任务:
bash
# 每 5 分钟检查一次
*/5 * * * * /path/to/nfs_monitor.sh