平均负载高,CPU 使用率低 - 为什么?

Spi*_*iff 92 solaris performance

我们在 Web 应用程序上看到了巨大的性能问题,我们正试图找到瓶颈。我不是系统管理员,所以有些东西我不太明白。一些基本调查显示 CPU 处于空闲状态,有大量内存可用,没有交换,没有 I/O,但平均负载很高。

此服务器上的软件堆栈如下所示:

  • Solaris 10
  • 爪哇 1.6
  • WebLogic 10.3.5(8 个域)

在此服务器上运行的应用程序与另一台服务器上的 Oracle 数据库进行通信。

这台服务器有 32GB 的 RAM 和 10 个 CPU(我认为)。

运行prstat -Z给出了这样的东西:

   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
  3836 ducm0101 2119M 2074M cpu348  58    0   8:41:56 0.5% java/225
 24196 ducm0101 1974M 1910M sleep   59    0   4:04:33 0.4% java/209
  6765 ducm0102 1580M 1513M cpu330   1    0   1:21:48 0.1% java/291
 16922 ducm0102 2115M 1961M sleep   58    0   6:37:08 0.0% java/193
 18048 root     3048K 2440K sleep   59    0   0:06:02 0.0% sa_comm/4
 26619 ducm0101 2588M 2368M sleep   59    0   8:21:17 0.0% java/231
 19904 ducm0104 1713M 1390M sleep   59    0   1:15:29 0.0% java/151
 27809 ducm0102 1547M 1426M sleep   59    0   0:38:19 0.0% java/186
  2409 root       15M   11M sleep   59    0   0:00:00 0.0% pkgserv/3
 27204 root       58M   54M sleep   59    0   9:11:38 0.0% stat_daemon/1
 27256 root       12M 8312K sleep   59    0   7:16:40 0.0% kux_vmstat/1
 29367 root      297M  286M sleep   59    0  11:02:13 0.0% dsmc/2
 22128 root       13M 6768K sleep   59    0   0:10:51 0.0% sendmail/1
 22133 smmsp      13M 1144K sleep   59    0   0:01:22 0.0% sendmail/1
 22003 root     5896K  240K sleep   59    0   0:00:01 0.0% automountd/2
 22074 root     4776K 1992K sleep   59    0   0:00:19 0.0% sshd/1
 22005 root     6184K 2728K sleep   59    0   0:00:31 0.0% automountd/2
 27201 root     6248K  344K sleep   59    0   0:00:01 0.0% mount_stat/1
 20964 root     2912K  160K sleep   59    0   0:00:01 0.0% ttymon/1
 20947 root     1784K  864K sleep   59    0   0:02:22 0.0% utmpd/1
 20900 root     3048K  608K sleep   59    0   0:00:03 0.0% ttymon/1
 20979 root       77M   18M sleep   59    0   0:14:13 0.0% inetd/4
 20849 daemon   2856K  864K sleep   59    0   0:00:03 0.0% lockd/2
 17794 root       80M 1232K sleep   59    0   0:06:19 0.0% svc.startd/12
 17645 root     3080K  728K sleep   59    0   0:00:12 0.0% init/1
 17849 root       13M 6800K sleep   59    0   0:13:04 0.0% svc.configd/15
 20213 root       84M   81M sleep   59    0   0:47:17 0.0% nscd/46
 20871 root     2568K  600K sleep   59    0   0:00:04 0.0% sac/1
  3683 ducm0101 1904K 1640K sleep   56    0   0:00:00 0.0% startWebLogic.s/1
 23937 ducm0101 1904K 1640K sleep   59    0   0:00:00 0.0% startWebLogic.s/1
 20766 daemon   5328K 1536K sleep   59    0   0:00:36 0.0% nfsmapid/3
 20141 daemon   5968K 3520K sleep   59    0   0:01:14 0.0% kcfd/4
 20093 ducm0101 2000K  376K sleep   59    0   0:00:01 0.0% pfksh/1
 20797 daemon   3256K  240K sleep   59    0   0:00:01 0.0% statd/1
  6181 root     4864K 2872K sleep   59    0   0:01:34 0.0% syslogd/17
  7220 ducm0104 1268M 1101M sleep   59    0   0:36:35 0.0% java/138
 27597 ducm0102 1904K 1640K sleep   59    0   0:00:00 0.0% startWebLogic.s/1
 27867 root       37M 4568K sleep   59    0   0:13:56 0.0% kcawd/7
 12685 ducm0101 4080K  208K sleep   59    0   0:00:01 0.0% vncconfig/1
ZONEID    NPROC  SWAP   RSS MEMORY      TIME  CPU ZONE
    42      135   22G   19G    59%  87:27:59 1.2% dsuniucm01

Total: 135 processes, 3167 lwps, load averages: 54.48, 62.50, 63.11
Run Code Online (Sandbox Code Playgroud)

我知道CPU大多是空闲的,但是平均负载很高,这对我来说很奇怪。内存好像没有问题。

运行vmstat 15给出了这样的东西:

 kthr      memory            page            disk          faults      cpu
 r b w   swap  free  re  mf pi po fr de sr s0 s1 s4 sd   in   sy   cs us sy id
 0 0 0 32531400 105702272 317 1052 126 0 0 0 0 13 13 -0 8 9602 107680 10964 1 1 98
 0 0 0 15053368 95930224 411 2323 0 0 0 0 0 0  0  0  0 23207 47679 29958 3 2 95
 0 0 0 14498568 95801960 3072 3583 0 2 2 0 0 3 3  0 21 22648 66367 28587 4 4 92
 0 0 0 14343008 95656752 3080 2857 0 0 0 0 0 3 3  0 18 22338 44374 29085 3 4 94
 0 0 0 14646016 95485472 1726 3306 0 0 0 0 0 0 0  0  0 24702 47499 33034 3 3 94
Run Code Online (Sandbox Code Playgroud)

我知道 CPU 大部分是空闲的,没有进程在队列中等待执行,很少发生交换。

运行iostat 15给出了这个:

   tty        sd0           sd1           sd4           ssd0           cpu
 tin tout kps tps serv  kps tps serv  kps tps serv  kps tps serv   us sy wt id
   0  676 324  13    8  322  13    8    0   0    0  159   8    0    1  1  0 98
   1 1385   0   0    0    0   0    0    0   0    0    0   0    0    3  4  0 94
   0  584  89   6   24   89   6   25    0   0    0  332  19    0    2  1  0 97
   0  296   0   0    0    0   0    0    0   0    0    0   0    0    2  2  0 97
   1 1290  43   5   24   43   5   22    0   0    0  297  20    1    3  3  0 94
Run Code Online (Sandbox Code Playgroud)

运行netstat -i 15给出以下内容:

    input   aggr26    output       input  (Total)    output
packets errs  packets errs  colls  packets errs  packets errs  colls
1500233798 0     1489316495 0     0      3608008314 0     3586173708 0     0
10646   0     10234   0     0      26206   0     25382   0     0
11227   0     10670   0     0      28562   0     27448   0     0
10353   0     9998    0     0      29117   0     28418   0     0
11443   0     12003   0     0      30385   0     31494   0     0
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Spi*_*iff 45

通过进一步调查,似乎性能问题主要是由于两个系统(Oracle SSXA 和 UCM)之间的大量网络调用造成的。调用速度快但数量多且序列化,因此 CPU 使用率低(主要是等待 I/O),平均负载高(许多调用等待处理),尤其是响应时间长(通过累积小响应时间)。

感谢您对这个问题的洞察!

  • 你是如何确认并弄清楚这一点的?我们看到了同样的问题,想检查一下我们是否有同样的问题 (17认同)

web*_*toe 32

当您说“高平均负载”时,我假设您的意思是 prstat 在输出数字的底部显示“平均负载”

Total: 135 processes, 3167 lwps, load averages: 54.48, 62.50, 63.11
Run Code Online (Sandbox Code Playgroud)

这些数字看起来与 top 提供的数字相似,可能意味着正在运行的进程的平均队列大小。这不是正在使用的处理器时间的百分比,而是有多少“事物”正在骚扰 CPU 以争取运行时间。诚然,这些看起来确实很高,但这一切都取决于您正在运行的应用程序;一旦他们获得了他们的位置,这些过程实际上可能不会做太多事情。有关 top 的详细解释,请参见此处

我对 WebLogic 不熟悉,但我注意到,一般来说,使用 Apache Tomcat 可以同时产生许多 Java 线程来处理看起来并不多的请求。这可能是导致这些高平均负载数的原因。确保您在适当的情况下使用连接池连接到后端,并考虑增加应用程序可用于处理连接的空闲线程数(不确定您如何在 WebLogic 上执行此操作;Tomcat 具有每个连接器线程池或一个通用的执行器线程池)。如果您不这样做,则可能会产生全新的线程来处理请求。

至于性能,您需要确定应用程序的哪个部分受到影响。是发生在 WebLogic/Java 方面的处理、数据库访问、DNS 查找(如果出于某种原因进行...)、网络问题还是操作系统上的某些问题。

99% 的时间是你的代码以及它如何与数据库进行交互。然后它将是 Web 应用程序的配置。在这一点之后,您将致力于从应用程序中挤出最后几毫秒,或者考虑使用相同的硬件提供更高的并发性。对于这种更细粒度的性能调整,您需要指标。

对于 Java,我建议安装Java Melody。它可以提供有关您的程序正在做什么的大量信息,并有助于缩小程序花费时间的范围。我只将它与 Tomcat 一起使用,但应该可以与任何 Java EE 容器/servlet 一起使用。

您可以通过多种方式调整 Java,因此请查看它们的性能指南(我确定您可能已经看过)并确保您设置了适合您的程序的正确堆大小等。Java Melody 可以帮助您跟踪您正在使用的 Java 堆的大小以及垃圾收集器的工作强度/它中断您的程序以清除对象的频率。

我希望这有帮助。如果您提供更多信息,我可能会更新此答案并使其更符合您的需求。

  • 我还会检查“mpstat 1 5”的输出以查看每个处理器的统计信息并查看“csw”和“syscl”列。从上面的 vmstat 看来,您正在执行大量系统调用和上下文切换,这似乎证实了 webtoe 的怀疑,即您有很多线程(Solaris 称它们为 LWP-LightWeight 进程)不断骚扰 CPU。它们在运行时都没有做太多事情,但许多人都在等待运行,因此平均负载很高。 (4认同)

rog*_*ack 28

作为旁注,平均负载还包括等待磁盘活动(即骚扰磁盘)的内容以及等待 CPU 的内容,它是两者的总和……因此您可能在其中一个或另一个中遇到问题。

请参阅http://en.wikipedia.org/wiki/Load_(computing) “Linux 还包括 [在其平均负载中] 处于不间断睡眠状态(通常等待磁盘活动)的进程”

作为旁注,我遇到的特殊问题是我的平均负载很高,但也有很多空闲的 cpu 和低磁盘使用率。

看来,至少在我的情况下,等待 I/O 的线程/进程有时会出现在平均负载中,但不会导致“等待”列的增加。但它们仍然受 I/O 限制。

如果您在 jruby 中运行它(仅执行 100 个线程,每个线程有大量 I/O),您可以看出以下代码就是这种情况:

100.times { Thread.new { loop { File.open('big', 'w') do |f| f.seek 10_000_000_000; f.puts 'a'; end}}}
Run Code Online (Sandbox Code Playgroud)

这给出了这样的顶级输出:

top - 17:45:32 up 38 days,  2:13,  3 users,  load average: 95.18, 50.29, 23.83
Tasks: 181 total,   1 running, 180 sleeping,   0 stopped,   0 zombie
Cpu(s):  3.5%us, 11.3%sy,  0.0%ni, 85.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  32940904k total, 23239012k used,  9701892k free,   983644k buffers
Swap: 34989560k total,        0k used, 34989560k free,  5268548k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
31866 packrd    18   0 19.9g  12g  11m S 117.0 41.3   4:43.85 java
  912 root      11  -5     0    0    0 S  2.0  0.0   1:40.46 kjournald
Run Code Online (Sandbox Code Playgroud)

所以你可以看到它有很多空闲的 cpu,0.0%wa,但是平均负载非常高。

iostat 同样显示磁盘基本空闲:

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
       9.62    0.00    8.75    0.00    0.00   81.62

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00    49.00  0.00  6.40     0.00   221.60    69.25     0.01    0.81   0.66   0.42
sda1              0.00    49.00  0.00  6.40     0.00   221.60    69.25     0.01    0.81   0.66   0.42
sda2              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
Run Code Online (Sandbox Code Playgroud)

另见http://linuxgazette.net/141/misc/lg/tracking_load_average_issues.html

作为进一步的旁注,这似乎也意味着(至少在这种情况下 - 运行 CentOS)平均负载在总数中分别包括每个线程。

  • “平均负载还包括等待磁盘活动的东西”*在 Linux* 上,而这个问题最初是关于 Solaris,它[似乎只包括负载平均中的运行和可运行(即等待 CPU)任务](https://serverfault .com/q/348933/58957)。这个问题的一个 Linux 版本是 [this](https://serverfault.com/q/482832/58957)。 (2认同)

PJu*_*ior 7

今天遇到了同样的问题。经过一些研究和诊断后,我意识到我的小型 VPS的磁盘用完了

在 shell/提示 (Linux/Unix) 类型中

df -h
Run Code Online (Sandbox Code Playgroud)

查看您机器上的可用磁盘。如果您的磁盘不足,则可能是问题/问题。


小智 6

尝试nmon

在这种情况下另一个有用的工具是nmon

它在一个小包中提供了多种查看其他工具提供的相同数据的方法。

如果这是无法缓存的内容,我建议将多个服务器放置在负载均衡器(例如 TCP 模式下的 haproxy)后面以分配负载。