`cat /proc/$pid/cmdline` 怎么会花费几秒钟?

`cat /proc/$pid/cmdline` 怎么会花费几秒钟?

昨天我在我们的一台服务器上遇到了这种奇怪的行为。pspgrep并且htop(启动时)非常慢。strace ps表明read('/proc/$pid/cmdline)在某些进程上花费了几秒钟。为什么会发生这种情况?

一些观察结果:

  • 进程可执行文件位于 NFS 上
  • 进程(大约 20 多个)也在 NFS 上并行执行unlinksymlink操作文件
  • 它们是从同一个父进程派生的
  • 有 80GB 可用 RAM(大部分是缓存),但交换区(仅 4GB)已被充分使用
  • 我运行while true; do cat /proc/$pid/status; sleep .1; done,如果是或则cat立即返回,但当是时花了几秒钟StateSRStateD

我做了一些谷歌搜索,发现了一些答案,表明当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

谢谢。

相关内容