故障排除-服务器负载篇


服务器为什么这么慢?耗尽了CPU、RAM和磁盘I/O资源

系统负载

uptime [root@shubei-182 ~]# uptime 16:17:20 up 39 days, 6:46, 3 users, load average: 0.15, 0.13, 0.14 load average后面的3个数字分别代表了1分钟、五分钟、15分钟内机器的平均负载。一个系统平均负载等与处于运行或者不可打扰状态进程的平均数。可运行的进程要么正在使用CPU,要么等待使用CPU;不可打扰状态的进程都在等待I/O响应 平均负载为1的单CPU系统意味着这个CPU处于恒定负载。如果单CPU系统的平均负载是4,那么这个系统处于它可承受负载能力的4倍,所以3/4的进程都在等待资源。一个系统的平均负载不会因为你所拥有的CPU数量而更改,所以,如果具备两个CPU 的系统的平均负载是1,那么其中一个CPU—直处于满负荷状态,也就是说,系统处于50%的负载状态。所以,负载状态为1的单 CPU系统与负载状态为4的四CPU系统使用资源的量—样。 什么是高负载

—个值得研究的问题是:平均负载多少算高?简单的冋答是 “这取决于产生高负载的原因”。闪为负载描述了TH在侦州资源的活 动进程的平均数量,所以负载的飙升透露了很多信息。明确负载是 CPU密集型(等待CPU资源的进程) 、 RAM密集型(尤其是,频繁 使用的RAM被移入了交换区)还是I/O密集型(争夺磁盘或网络1/ 0资源的进程)非常重要。 例如,如果运行的一个应用程序在不同的时间点产生大量的同 少线程,这些线程会N时后动,你可能会看到负载飙升到20、40或 打史卨,它们在竞争系统资源。随着这些进程逐渐完成,负载就会 降下来。 例如,如果运行的一个应用程序在不同的时间点产生大量的同 步线程,这些线程会N时后动,你可能会看到负载飙升到20、40或 打史卨,它们在竞争系统资源。随着这些进程逐渐完成,负载就会 降下来。 通 常CPU密集型的系统会比I/ O密集型的系统响应度更高。我 见过数以百计CPU密集沏的系统,我仍然可以在这些系统上运行故 障排除工具而 R具有良好的响应时 N。我也见过 I/ O负载相对较低 的丨/〇密集增系统,只是登录这些系统就需要花费一段时间,因为 它们的磁盘I/O完企饱和了。用尽RAM资源的系统通常与I/O密集型的系统表现相同,因为一旦系统开始使用磁盘上的交换存储,他就会消耗磁盘资源,导致进程逐渐变慢直至停止。 用top命令解决负载问题

当需要解决高负载问题的时候,我第一个想到的工具是top命 令。在命令行输入top命令并按下Enter•键后,马上就能看到大量的 系统信息(见图2-1 )。这些数据都会不断更新,所以你能看到系统的 实时信息,包括系统启动了多久、负载平均值、系统中总共有多少进 程正在运行、总共有多少内存、使用了多少内存、还剩多少内存,最 后还包含系统的进程列表以及它们占用的资源数量。使用top命令可 能无法看到系统当前运行的所有进程,W为无法将它们都显示在屏幕 上。top命令默认排序方式是按照进程的CPU使用情况从上到下排序, 所以可以一眼就能看到哪些进程正在消耗CPU资源。 那么如果发现一个进程占用了全部CPU资源,你想要终止这个 进程,该怎么做呢? top命令输出的第一列是PID,它代表程序的 进 程1D——系统赋给每个进程的唯一 ID。想要终止某个进程,只 需按下K按键,然后输人想要终止的PID,最后当系统提示该进程 将会终止于signal_15时,按下Enter键即可。 默认情况下top命令在非交互式模式下运行,如果不需要看显 示在屏幕外的信息,那一切都还好。如果想要看到top命令的完整 输出,或者想将这些信息都重定向到文件中,那么你可以在批处理 模式下运行这个命令。七选项可以幵幻批处理模式,-n选项可以控 制在退出top命令之前,刷新信息多少次。例如,想看到完整的输 出,仅需运行一次top命令,输人如下命令: top -b -n 1 了解top命令的输出

使用top命令来排除系统负载问题时,基本步骤是检查top的 输出,借此明确耗尽丫哪些资源(CPU、RAM还是磁盘丨/0)。一n 清楚了这个问题,就可以尝试检查到底是哪些进程大S消耗了这些 资源。首先,检查系统中top命令的标准输出:

top - 16:43:10 up 39 days, 7:11, 3 users, load average: 0.17, 0.16, 0.14

Tasks: 327 total, 1 running, 326 sleeping, 0 stopped, 0 zombie

%Cpu(s): 0.3 us, 0.1 sy, 0.0 ni, 99.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

KiB Mem : 65760184 total, 49271024 free, 4475296 used, 12013864 buff/cache

KiB Swap: 0 total, 0 free, 0 used. 56894196 avail Mem

us: 用户CPU时间

运行非优雅的用户进程所占CPU时间的百分比(优雅,英文“nicing”,是指一个今晨给允许你根据其他进程更改优先级)

sy:系统CPU时间

运行内核和内核进程所占CPU时间的百分比

ni:优雅CPU时间

如果更改过一些进程的优先级,这个指标能够告诉你他们所占的CPU时间的百分比

id:CPU空闲时间(idle)

这是你希望具备很高数值度量指标中的一个。它代表了CPU的空闲时间比。如果系统运行缓慢,但是这个指标特别高,那么你就可以确定问题的原因不是高CPU负载。

wa:I/O等待

这个数字代表了CPU时间用在等待执行I/O操作所占的百分比。当你解决运行缓慢的系统问题的时候,这是一个非常有价值的度量指标,因为如果这个数值很低,那么就能轻松排除磁盘或者网络I/O问题。

hi:硬件中断

CPU用在处理硬件终端所占时间的百分比

si:软件中断

CPU用在处理软件终端所占时间的百分比

st:流逝的时间

如果你正在运行虚拟机,这个度量指标会告诉你虚拟机中执行的其他任务所占CPU时间的百分比

在前面的例子中,你可以ft到系统有超过50%的空闲时间,这 与机器具备4个CPU、系统负载力1.70的指标相叫配。当你处理一 个运行缓慢的系统的时候,荇先要观察的度M指标之一就是I/ O等 待时间,它可以⑴来排除磁盘丨/〇的问题。如采丨/0等待时间很低, 那么可以看看CPU空闲时间百分比;如來丨/〇等待时间很高,那么 下步就是确定是什么因素导致I/ O等待时间所占的比常这么高, 这一点我马上就会Uf到。如果I/ O等待和CPU空闲时间W分比邰很 低,那么很可能会吞到一个非常高的用户时间百分比,所以你必须 确定是什么原闪导致了这么高的用户时N百分比。如果丨/〇等待时 问所占分比很低,而空闲时间 百分比很高,那么你就知道系统运 行缓慢不是CPU资源的原因,而应该该从別的地方找原闪。这可能意味着应该查看 网络问题或者Web服务器的问题,或者查看MySQL查询缓慢的问题等。

解决高I/O等待时间问题

[root@shubei-182 ~]# iostat 2 --->每两秒输出一次

Linux 3.10.0-693.el7.x86_64 (shubei-182) 2020年05月12日 x86_64 (24 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle

0.65 0.00 0.20 0.01 0.00 99.13 Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn

sda 6.96 0.31 40.21 1058509 136685437

sdc 0.01 0.07 0.00 243104 3504

sdb 0.00 0.00 0.00 16069 2050

dm-0 1.87 0.26 9.49 878063 32245428

dm-1 0.00 0.00 0.00 3132 0

dm-2 4.71 0.04 30.72 143845 104437940

首先看到的是与top命令相似的CPU信息,下面紧接着系统上所有硬盘设备及其分区的I/O状态信息。下面是各列代表的意义:

tps:这个值列出了设备每秒的传输量。传输(transfer)是向设备发送I/O请求的另一种表达方式

blk_read/s: 表示每秒从设备读取的数据量

blk_wrtn/s: 表示每秒向设备写入的数据量

blk_read: 表示从设备读取的数据总量

blk_wrtn 表示向设备写入的数据总量

当系统处于高I/O负载状态的时候,首先就是观察每个分区, 看看哪个分区的I/O负载最高。比如说,你有一台数据库服务器. 数据库本身存储在/dev/ sda3分K。你如果看到大量的1/0操作来自 这里,这就是一个很好的线索:数据库很可能占用了大量I/O资源。 弄明内了这一点后,下一步就是确定I/O操作大部分来自读取 还是写入。假设你怀疑备份工作导致了 I/O操作的增长。因为备份 工作的操作主要集中于从文件系统中读取文件,然后通过网络传输 到备用服务器,如果大量的I/O操作都来自于写入而不是读取操作, 那么大概就可以排除这个问题。

  • iotop

Total DISK READ : 0.00 B/s | Total DISK WRITE : 0.00 B/s Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 1 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % systemd --system --deserialize 20 2 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kthreadd] 3 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [ksoftirqd/0] 在这个例子中可以看到没有进程占用大量I/O读取操作 问题发生后的高负载处理

截止到这里,本章都在讨论3系统负载过高的时候,如何找到 卨负载的丨京丨六丨。尽管top和 iostat都坫非常优秀的丁具,但是,系 统发生问题的时候,我们不是总能足够幸运地找到解决办法。我记 不清我遇到过多少次机器运行缓慢,只能等待负载降低才能登录。 只耑要稍微多做一点工作就能在服务器上安装相应的工具,记录 全天的性能数据。 我们已经讨论了如何使用 sysstat包中的 iostat工具来解决高 I/O 的问题,不过 sysstat中也包含一些能报告 CPU和 RAM使用情况 的工具。虽然的确可以使用top命令达到这个目的,但是sysstat 更加强大,它能够川一种简中.的机制來 id录系统的统计信息,如 CPU负载 、RAM以及丨/0状态。借助这些统计信息,当有人抱怨 咋天中午系统很慢时,你就可以查看日志,看肴是什么原因引起 的这个问题。 配置sysstat

在基于 Red Hat的系统上,你可能需要修改/ etc/ sysconfig/ sysstat文件,更改 HISTORY选项,让它可以记录7天以上的统汁 信息。对于这两种系统,统计信息都可以每10分钟抓取一次并记 录每日总结。 一旦启用了 sysstat,它就会每10分钟收集一次系统状态并将它 们存储到/ var/ log/ sysstat或 / var/ log/ sa文件中。除此之外,每天晚 上在午夜之前,它还会分割统计文件。这些操作都是由/ etc/ cron.d/ sysstat脚本执行的,所以如果想要吏改 sysstat收集信息的频率,你 可以修改这个脚本文件。 查看CPU统计信息

sysstat统计信息的时候,它将这些信息存储在以 sa开头、以本 月当前日期结尾的文件名的文件中(如 sa03)。这就意味着你可以 查看从当前日期起,一个月以内的统计数据。使用 sar工具可以査 看这些统计信息。默认情况下sar会输出当天的CPU统计信息: sar Linux 3.10.0-514.26.2.el7.x86_64 (iz2zecjgiw17pjw9ppdavtz) 05/12/2020 x86_64 (1 CPU) 06:20:01 PM CPU %user %nice %system %iowait %steal %idle 06:30:01 PM all 1.10 0.00 0.63 0.03 0.00 98.24 Average: all 1.10 0.00 0.63 0.03 0.00 98.24 从输出中可以发现,CPU的很多统计信息都和top命令的输出相同。在最后一行,sar还为每个值提供了平均值 查看内存统计信息

sar -r Linux 3.10.0-514.26.2.el7.x86_64 (iz2zecjgiw17pjw9ppdavtz) 05/12/2020 x86_64 (1 CPU) 06:20:01 PM kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty 06:30:01 PM 145036 1738688 92.30 83628 820448 2103632 111.67 1271260 338596 32 Average: 145036 1738688 92.30 83628 820448 2103632 111.67 1271260 338596 32 在这里可以看到使用了多少内存,空闲多少内存,同时还能查看交换空间的信息以及文件缓存的信息,这些信息与用too或free命令输出的信息蕾丝。与之不同的是,你可以及时查看之前的信息 查看磁盘统计信息

sar -b Linux 3.10.0-514.26.2.el7.x86_64 (iz2zecjgiw17pjw9ppdavtz) 05/12/2020 x86_64 (1 CPU) 06:20:01 PM tps rtps wtps bread/s bwrtn/s 06:30:01 PM 0.54 0.08 0.45 3.94 7.26 Average: 0.54 0.08 0.45 3.94 7.26 从这里可以看到每秒总共传输到数据量(tps),它由总共读区到数据量和写入到数据量(分别是rtps和wtps)相加获得。bread/s列并非用来衡量块I/O,而是告诉你平均每秒读取的数据量。类似的,bwrtn/s能告诉你平均每秒写入的数据量 查看之前的统计信息

使用-s和-e参数分别制定你感兴趣的开始时间和结束时间。例如想看8:00pm--8:30pm 这个时间段的CPU数据,需要输入: sar -s 20:00:00 -e 20:30:00