Linux 中的命令执行时间缓慢

Linux 中的命令执行时间缓慢

超级用户建议我去这里。

我们在 Linux 中遇到了一些简单命令执行时间缓慢的问题,这可能与 procfs 速度缓慢有关。

类似简单的uptime命令可能需要几秒钟才能执行。

输入如下:

  • 平台:AWS
  • 实例:x1.32xl(128 核,2T RAM)
  • 操作系统:Ubuntu 16.04
  • 内核:4.4.0-1043-aws

我们运行大约有 250 个容器的 docker。

  • Docker 版本:17.09-ce

利用率:

  • CPU 利用率:<50%
  • 内存利用率:<50%

一些操作系统统计数据:

# cat /proc/loadavg
100.45 108.30 109.41 35/254951 544357

# vmstat 1 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
110  2 791584 485552640 50354496 687472448    0    0   426   183    1    1 10  8 82  1  0
13  0 791584 485495104 50353940 687477568    0    0 22820 47984 196555 326943 12 12 75  1  0
33  1 791584 485385632 50352428 687473536    0    0 38932 52892 166486 389428 13 14 72  1  0

# ps axu| wc -l
3792

究竟发生了什么?

当命令以任何方式使用 procfs 时,启动简单命令需要时间。例如,ls在包含几个文件的目录中执行操作会卡在 procfs 的打开系统调用上

# strace -r ls
...
0.000084 open("/proc/filesystems", O_RDONLY) = 3
3.652504 fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
...

或者uptime

# strace -r uptime
...
0.000035 open("/proc/filesystems", O_RDONLY) = 3
11.014154 fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
...
0.000044 open("/proc/uptime", O_RDONLY) = 3
1.554646 lseek(3, 0, SEEK_SET)
...

快速问答以及我们已经尝试过的方法:

  • 这种缓慢仅存在于主机级别。在容器中我们没有看到这样的问题。我们尝试了一下,在使用以下方法运行容器时看到了这个问题:两个都 --ipc=host--pid=host旗帜。
  • 我们已经将 procfs 中的缓慢问题追溯到 mutex_lockhttps://github.com/torvalds/linux/blob/v4.4/fs/namei.c#L3082
  • 容器太多
    • 不,我们在其他主机上有 600 个,一切正常
  • 工序过多
    • 不,我们在其他主机上有 10K,一切正常
  • 线程过多
    • 可能是这样。我们在任何其他主机上都没有这么多线程,但我们尝试在干净的 x1.32xlarge 实例上重现它,但失败了。所以它可能是线程 + 其他东西。

欢迎任何想法和建议。

答案1

我们找到了根本原因。

我们跑

/usr/share/bcc/tools/funcslower -m 250 -T proc_pid_readdir

获取导致长时间调用的进程proc_pid_readdir

当我们这样做时,我们得到了几个流程:

zabbix_agent
atop
byobu

所有这些人的通话时间都非常长。

TIME       COMM           PID    LAT(ms)             RVAL FUNC
20:01:35   zabbix_agentd  921144 1258.01                0 proc_pid_readdir 
20:01:38   zabbix_agentd  921144 2692.71                0 proc_pid_readdir 
20:01:39   zabbix_agentd  921145 1276.88                0 proc_pid_readdir

当我们停止所有这些时,我们看到了巨大的进步。

因此,看起来混合大量进程和线程 + 调用过于proc_pid_readdir频繁会导致 procfs 速度非常慢。

我们今天将尝试 4.14 内核,看看它是否会变得更好。

更新:

内核 4.14 也解决了我们的问题。每个 inode 的简单互斥锁现在被替换为rwsem

相关内容