昨天我在我们的一台服务器上遇到了这种奇怪的行为。ps
,pgrep
并且htop
(启动时)非常慢。strace ps
表明read('/proc/$pid/cmdline
)在某些进程上花费了几秒钟。为什么会发生这种情况?
一些观察结果:
- 进程可执行文件位于 NFS 上
- 进程(大约 20 多个)也在 NFS 上并行执行
unlink
和symlink
操作文件 - 它们是从同一个父进程派生的
- 有 80GB 可用 RAM(大部分是缓存),但交换区(仅 4GB)已被充分使用
- 我运行
while true; do cat /proc/$pid/status; sleep .1; done
,如果是或则cat
立即返回,但当是时花了几秒钟State
S
R
State
D
我做了一些谷歌搜索,发现了一些答案,表明当State
是时D
,阅读/proc/$pid/cmdline
会停止。真的吗?那是如何运作的呢?为什么/proc/$pid/cmdline
在程序启动之前设置的 会受到程序启动后所做的事情的影响?
答案1
同样在这里,读取 /proc/$pid/cmdline 以获得特殊的 $pid 非常慢,即使 State 为 R 也是如此。感谢上面的链接指出它可能与 NUMA 有关,我发现它是由 numad 移动进程引起的从节点到节点,这是来自 /var/log/numad.log :
Thu Jul 18 20:06:41 2019: Advising pid 9565 ($name) move from nodes (0-1) to nodes (1)
Thu Jul 18 20:06:45 2019: PID 9565 moved to node(s) 1 in 3.91 seconds
Thu Jul 18 20:11:50 2019: Advising pid 9565 ($name) move from nodes (1) to nodes (1)
Thu Jul 18 20:12:00 2019: PID 9565 moved to node(s) 1 in 9.72 seconds
Thu Jul 18 20:17:05 2019: Advising pid 9565 ($name) move from nodes (1) to nodes (1)
Thu Jul 18 20:17:23 2019: PID 9565 moved to node(s) 1 in 17.85 seconds
Thu Jul 18 20:22:28 2019: Advising pid 9565 ($name) move from nodes (1) to nodes (1)
Thu Jul 18 20:22:51 2019: PID 9565 moved to node(s) 1 in 22.73 seconds
Thu Jul 18 20:27:56 2019: Advising pid 9565 ($name) move from nodes (1) to nodes (1)
Thu Jul 18 20:28:23 2019: PID 9565 moved to node(s) 1 in 26.88 seconds
Thu Jul 18 20:33:28 2019: Advising pid 9565 ($name) move from nodes (1) to nodes (1)
Thu Jul 18 20:33:44 2019: PID 9565 moved to node(s) 1 in 15.49 seconds
当移动进程时,读取cmdline很慢,因为cmdline来自用户空间,而内核需要锁定(?)页面并读取。
我猜想稍后需要从同一节点1移动到节点1,因为进程9565位于节点1上,但它可能使用远程内存。
% numactl -s
policy: default
preferred node: current
physcpubind: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
cpubind: 0 1
nodebind: 0 1
membind: 0 1
谢谢。