ps aux 因 Java 进程 CPU/IO 过高而挂起

ps aux 因 Java 进程 CPU/IO 过高而挂起

我在 java 进程和 nrpe 检查方面遇到了一些问题。我们有一些进程有时会在 32 核系统上使用 1000% 的 CPU。系统响应非常灵敏,直到你执行

ps aux 

或者尝试在 /proc/pid# 中执行任何操作,例如

[[email protected] /proc/18679]# ls
hangs..

ps aux 的 strace

stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2819, ...}) = 0
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2819, ...}) = 0
stat("/dev/pts1", 0x7fffb8526f00)       = -1 ENOENT (No such file or directory)
stat("/dev/pts", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
readlink("/proc/15693/fd/2", "/dev/pts/1", 127) = 10
stat("/dev/pts/1", {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0
write(1, "root     15693 15692  0 06:25 pt"..., 55root     15693 15692  0 06:25 pts/1    00:00:00 ps -Af
) = 55
stat("/proc/18679", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/18679/stat", O_RDONLY)      = 5
read(5, "18679 (java) S 1 18662 3738 3481"..., 1023) = 264
close(5)                                = 0
open("/proc/18679/status", O_RDONLY)    = 5
read(5, "Name:\tjava\nState:\tS (sleeping)\nT"..., 1023) = 889
close(5)                                = 0
open("/proc/18679/cmdline", O_RDONLY)   = 5
read(5,

java 进程正在运行并将正常完成,但问题是它使我们的监控变得疯狂,认为进程已经关闭,因为它在等待 ps aux 完成时超时了。

我试过做类似的事情

 nice -19 ionice -c1 /usr/lib64/nagios/plugins/check_procs -w 1:1 -c 1:1 -a 'diamond' -u root -t 30

没有运气

编辑

系统规格

  • 32 核 Intel(R) Xeon(R) CPU E5-2650 0 @ 2.00GHz
  • 128GB 内存
  • 12 个 4TB 7200 硬盘
  • CentOS 6.5
  • 我不确定型号,但供应商是 SuperMicro

发生这种情况时的负载大约为 90-160 左右,持续 1 分钟。

奇怪的是,我可以进入任何其他 /proc/pid#,它工作得很好。当我通过 ssh 进入时,系统反应灵敏。比如当我们收到高负载警报时,我可以直接通过 ssh 进入。

另一项编辑

我一直在使用 deadline 作为调度程序

[[email protected] ~]# for i in {a..m}; do cat /sys/block/sd${i}/queue/scheduler; done
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq
noop anticipatory [deadline] cfq

安装看起来像

[[email protected] ~]# mount
/dev/sda3 on / type ext4 (rw,noatime,barrier=0)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/sda1 on /boot type ext2 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
/dev/sdb1 on /disk1 type xfs (rw,nobarrier)
/dev/sdc1 on /disk2 type xfs (rw,nobarrier)
/dev/sdd1 on /disk3 type xfs (rw,nobarrier)
/dev/sde1 on /disk4 type xfs (rw,nobarrier)
/dev/sdf1 on /disk5 type xfs (rw,nobarrier)
/dev/sdg1 on /disk6 type xfs (rw,nobarrier)
/dev/sdh1 on /disk7 type xfs (rw,nobarrier)
/dev/sdi1 on /disk8 type xfs (rw,nobarrier)
/dev/sdj1 on /disk9 type xfs (rw,nobarrier)
/dev/sdk1 on /disk10 type xfs (rw,nobarrier)
/dev/sdl1 on /disk11 type xfs (rw,nobarrier)
/dev/sdm1 on /disk12 type xfs (rw,nobarrier)

好的,我尝试安装调整并将其设置为吞吐量性能。

[[email protected] ~]# tuned-adm profile throughput-performance
Switching to profile 'throughput-performance'
Applying deadline elevator: sda sdb sdc sdd sde sdf sdg sdh[  OK  ] sdk sdl sdm
Applying ktune sysctl settings:
/etc/ktune.d/tunedadm.conf:                                [  OK  ]
Calling '/etc/ktune.d/tunedadm.sh start':                  [  OK  ]
Applying sysctl settings from /etc/sysctl.d/99-chef-attributes.conf
Applying sysctl settings from /etc/sysctl.conf
Starting tuned:                                            [  OK  ]

答案1

一般来说,我见过这种情况因为读取停滞而发生。您的输出证实了这一点。当您运行命令strace时,尝试读取 /proc/xxxx/cmdline 文件会挂起。ps aux

I/O 的瞬时峰值会耗尽系统资源。如果与存储子系统有关,则 90-160 的负载是极其糟糕的消息。

对于存储阵列,您能告诉我们是否有硬件 RAID 控制器吗?服务器上的主要应用程序是否具有写偏向性?您提到的磁盘(12 x 4TB)是低速近线 SAS 或 SATA 磁盘。如果没有写缓存在驱动器阵列前面,写入能够大大增加系统负载。如果这些是 Supermicro 背板上的纯 SATA 驱动器,请不要低估其他磁盘问题的可能性超时、驱动器故障、背板故障等)这是否在所有 Hadoop 节点上都会发生?

一个简单的测试是尝试iotop在发生这种情况时运行。此外,由于这是 EL6.5,您是否有任何tuned-adm设置是否已启用?是否已启用写入屏障?

如果您没有更改服务器的 I/O 提升器,ionice可能会产生影响。如果您将其更改为CFQ,(该服务器可能应该在最后期限),ionice不会有什么区别。

编辑:

我在生产环境中还看到了另一个奇怪的事情。这些是 Java 进程,我假设它们是多线程的。你的 PID 怎么样sysctl内核.pid_max? 我曾经遇到过 PID 耗尽并导致高负荷的情况。

另外,您提到了内核版本更新日志。它已有一年多历史,是 CentOS 6.4 版本的一部分,但您服务器的其余部分是 6.5。您是否在 yum.conf 中将内核更新列入黑名单?对于该系统,您可能应该使用内核 2.6.32-431.xx 或更新版本。你的旧内核可能存在大页面问题。如果您无法更改内核,请尝试使用以下命令禁用它们:

echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled

答案2

很明显,问题不是磁盘相关的问题。从挂起的 strace 可以清楚地看出这一点:

open("/proc/18679/cmdline", O_RDONLY)   = 5
read(5,

/proc 是内核和用户空间之间的接口。它根本不接触磁盘。如果在读取命令的参数时出现问题,通常是内核相关的问题,不太可能是存储问题。请参阅 @kasperd 评论。

负载只是问题的副作用,高数字并不能说明全部情况。您可能拥有一个负载非常高的服务器,但应用程序运行没有任何故障。

您可以获取有关 发生的情况的更多信息cat /proc/$PID/stack$PID读取停滞的进程 ID 在哪里。

对于您来说,我会从内核升级开始。

答案3

因此,即使经过了所有调整并升级到 CentOS 提供的最新 2.6 内核,我们仍然会看到挂起。虽然没有以前那么多,但还是可以看到。

修复方法是升级到 CentOS 在其 centosplus 存储库中提供的 3.10.x 系列内核。

http://mirror.centos.org/centos/6/xen4/x86_64/Packages/

这消除了所有进程树挂起。正如我所说,系统没有承受任何疯狂的负载,运行新进程不会很迅速。所以大多数是 2.6 内核的问题。

答案4

这是另一个修复。

看起来我们正在运行以下 raid 控制器

Adaptec 71605

我已经对所有受影响的机器进行固件更新至最新版本,似乎问题已经得到解决。

由于在 CentOS 6 上安装 3.10 时出现其他随机问题,我们不得不从 3.10 内核实验降级,但固件升级似乎解决了该问题。

相关内容