什么是平衡负载
首先大家思考一下,当你发现自己的服务变慢时,你会首先使用什么命令来排查?我通常做的第一件事,就是执行top或者uptime命令来了解系统的负载情况。比如像下面这样,我在命令行里输入top命令,它就会像Windows系统中的任务处理器那样显示各个进程的资源占用状况。
我在命令行里输入uptime 命令,系统也会随即给出以下结果:
update中的参数分别是什么意思呢?它们分别是当前时间、系统运行时间以及正在登录用户数、系统在过去的1分钟、5分钟和15分钟内的平均负载。
22:29 // 当前时间
up 3 days, 12:24 // 系统运行时间
2 user // 正在登录用户数
2.44 4.13 4.42 // 1分钟、5分钟和15分钟内的平均负载
我猜一定有人会说,平均负载不就是单位时间内的 CPU 使用率吗?上面的2.44,就代表CPU使用率是 244%,其实并不是这样。平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。
那具体的,什么是可运行状态和不可中断状态的进程?
可运行状态的进程:正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于Running(运行)状态或者Runnable(就绪)状态的进程。
不可中断状态的进程:正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的Uninterruptible Sleep状态也称为Disk Sleep的进程。比如当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题。所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制。
因此,你可以简单理解为,平均负载就是单位时间内的活跃进程数,但实际上是活跃进程数的指数衰减平均值。这个“指数衰减平均”的详细含义我们不用计较,这只是系统的一种更快速的计算方式,我们把它直接当成活跃进程数的平均值也没什么问题。
那么我们进一步思考一下,我们查看平均负载时,这个值为多少时比较合理呢?
平均负载为多少时合理
既然平均负载代表的是单位时间内的活跃进程数,那么在理想情况下,每个CPU都刚好运行着一个进程,可以使得CPU得到充分分利用。例如当负载为2时,对于双核CPU而言,意味着所有的 CPU 都刚好被完全占用。对于四核CPU而言,意味着有CPU有一半的空闲时间。而对于单核CPU而言,意味着有一半的进程竞争不到 CPU。
那么怎么能够直到自己的服务器有多少个CPU呢,可以使用以下命令进行查看:
$ grep 'model name' /proc/cpuinfo | wc -l
2
这样,我们就可以根据自己服务的CPU数量以及平均负载来判断我们系统是否是否出现过载,一般情况下,如果均负载比 CPU 个数还大的时候,系统就已经出现了过载。
新的问题又来了,我们在例子中可以看到平均负载有三个数值,到底该参考哪一个呢?实际上,我们都要看。三个不同时间间隔的平均值,其实给我们提供了分析系统负载趋势的数据来源,让我们能更全面、更立体地理解目前的负载状况。
假设我们在一个单 CPU 系统上看到平均负载为 1.73,3.60,7.98,那么说明在过去 1 分钟内,系统有 73% 的超载,在5分钟内有260%的超载,而在 15 分钟内,有 698% 的超载,从整体趋势来看系统的负载是在不断的降低的。
在实际的生产环境中,当平均负载高于 CPU 数量 70% 的时候,你就应该分析排查负载高的问题了。一旦负载过高,就可能导致进程响应变慢,进而影响服务的正常功能。70% 这个数字并不是绝对的,最推荐的方法,还是把系统的平均负载监控起来,然后根据更多的历史数据,判断负载的变化趋势。当发现负载有明显升高趋势时,比如说负载翻倍了,你再去做分析和调查。
平均负载与CPU使用率的关系
请你思考一个问题,平均负载代表的是单位时间内平均活跃进程数,那平均负载高了是否一定就意味着 CPU 使用率高?
其实并不一定,我们来具体分析一下。我们还是从平均负载的定义来,平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待 I/O 的进程。而CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。例如:
- 对于CPU 密集型进程而言,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
- 对于I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
- 而对于大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
小结
平均负载提供了一个快速查看系统整体性能的手段,反映了整体的负载情况。具体的,平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。但只看平均负载本身,我们并不能直接发现,到底是哪里出现了瓶颈。因为平均负载高有可能是 CPU 密集型进程导致的,还可能是I/O 更繁忙了。
本文涉及到的Linux命令
top:是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。
ps:用于显示当前进程的状态,与top的区别是top显示资源的动态变化,ps显示的是瞬时的状态。
uptime:能够打印系统总共运行了多长时间和系统的平均负载。 uptime命令可以显示的信息显示依次为:现在时间、系统已经运行了多长时间、目前有多少登陆用户、系统在过去的1分钟、5分钟和15分钟内的平均负载。