负载可以说是一个服务器是否正常的风向标,当接入的软件运行缓慢的时候,相信大部分人排查线上服务器第一件事就是要看下负载的高低?通过uptime命令可以直观的看到系统1、5、15分钟内的平均负载值,本文简称为负载。那么关于负载就有一些有意思的话题了。如什么是负载,如何判定负载的高低?那些原因导致负载升高?下面结合我的一些工作经验简单聊一聊。

什么是负载?

在我最早接触负载一词的时候,大脑里的印象就是衡量服务器的繁忙程度,因此服务器的负载不能太高,高了的话服务器就忙不过来了。我对负载这样的认识一直大概保持了一年半,后来还是因为有个原因,于是去man了下uptime。

关于负载的解释,uptime上有算是较为详细的说明:

System load averages is the average number of processes that are either in a runnable or uninterruptable state.  A process in a runnable state is either using the CPU or waiting to use the CPU.  A process  in  uninterruptable  state  is waiting for some I/O access, eg waiting for disk.  The averages are taken over the three time intervals.  Load averages are not normalized for the number of CPUs in a system, so a load average of 1 means a single CPU system is loaded all the time while on a 4 CPU system it means it was idle 75% of the time.

根据以上的描述,负载的概念就清晰起来了,首先负载是什么? 负载是一个平均进程数。那么,是所有状态下的进程数吗?不是的,对进程的状态有要求,就是进程的状态需要处于 runnable state(可运行状态)uninterrupttable state(不可中断状态)。 

ok,现在的重点来到了这两种状态的进程的理解上,何为 runnable 状态,上面也给出了清晰的解释,就是要么进程正在使用cpu,要么正在等待着使用cpu。对这句解释稍作补充,在一个进程的生命周期中,会有不同状态,处于runnable状态的进程代表着一切资源准备就绪了(cpu资源除外),那么就会有两种情况,一种是已经获得了cpu资源的,那么就代表着他正在使用cpu资源进行运行,另外一种就是他在排队等待cpu资源。(进程调度器会为使用cpu资源的进程维护一个队列)因为linux是多用户多进程系统,进程数量一般远大于cpu数量,因此cpu的资源是珍贵的,使用需要申请和排队。

何为uninterruptable 状态?,就是进程正在等待一些IO的请求,诸如磁盘IO/网络IO。说实在的,对于这个理解我还只能停留在表面。uninterruptable和 interruptable都是进程的sleep状态。我们可以理解为进程在睡觉(进程要继续运行的条件和资源不充分,因此他们要睡觉),进入这两种状态下,他们会立即释放掉cpu资源,不同点在于,处于interruptable是一种浅睡,任何的风吹草动(信号)都会惊醒他,然后他就会醒来接着干活。那么uninterruptable 就是一种沉睡,只有他等到的东西等来了他才醒来。

总结来说,负载数值即是处于runnable state 和uninterruptable state 的进程数。可以大致理解为系统正在处理的进程数

如何判断负载的高低?

记得毕业后刚入职几个月的时候,适逢双十一,上面分了几台小的服务器,让盯梢负载。然后,我问旭哥说多高负载算高,旭哥说超过1就很高了。所以,从此我就记住了,负载高于1就高了。直到有一次一个持有相同概念的同事被另外一个同事鄙视后,我偷偷弄明白了负载后,负载高于1就过载的说法就不攻自破了。

关于负载过1就过载的说法在只有一个cpu的情况下是可以理解的,因为一个cpu同一时刻只能处理一个进程,所以刚好是100%的满负荷运行。但是在一个四核的机器上,无异于其他三个cpu在空闲着。所以看负载是否过载,要有一个前提,那就是需要明确有几个cpu,如果负载数长时间高于cpu数,那么就可以判断为过载。

cat /proc/cpuinfo
以上命令可以查看cpu的个数。但这并不是说,我们都要线上的机器都要满负荷的去跑,肯定是要有一定的余量的,至于余多少,可以根据自己业务的访问情况决定。

那些原因导致负载升高?

有了对负载本质的了解,就不难分析出负载较高的情况了?导致负载升高的原因无非有两个原因,一个是处于 runnable state 的进程不断增多,另一个是处于 uninterruptable state的进程不断增多。runnable state 增多一般是cpu资源不够,而uninterruptable state增多大部分时间是磁盘IO成为瓶颈。

  • cpu资源不够,为了方便理解,我们可以假设机器只有一个cpu,而每个进程处理需要1s,但是每1s就会2个进程需要处理,此时每1过1s就会累积一个进程处理不掉,那么负载自然就不断的增加
  • IO成为瓶颈,有的时候cpu利用率不是很高,但是负载依然会很高,比如大量的读请求,导致磁盘io成为瓶颈,此时进程在等待磁盘IO的同时是不可中断的状态,因此仍然会参与负载值的计算,因此负载会变高

个人遇到的一些导致负载升高的原因

本人从事电商ERP系统开发,服务器中安装有mysql服务器,因此一般情况下,出问题大部分是mysql中的一些问题。

  • 大量数据请求时,包括搜索时全表扫描、以及大量的导出数据等。这种情况下一般大量的读请求让IO成为瓶颈,导致其他进程也处理缓慢,因此随着时间的增加负载就会升高
  • 事务未提交,一般一些业务处理系统,耦合关系强,如订单的出库和库存的关系,一般是需要原子性操作,这个时候一般会使用事务来进行控制,但是不幸出现事务未提交的情况,会导致大量资源被锁,其他请求处于长时间等待的情况,这种情况也会导致负载升高
  • 死锁,mysql的死锁检测以及回滚都会有一定的时间,加之事务对资源的独占,出现死锁会出现短暂的拥堵现象,同时负载的短时间内上升,不过后面继续会下降。但是死锁很频繁的情况下,负载也会一直较高。
  • 内存不足时,mysql服务器是相当耗费内存的,如果内存不足导致交换分区长时间使用的话,也会让机器负载升高
  • 其他导致的一些IO问题,如磁盘损坏以及磁盘空间不足

发表评论

电子邮件地址不会被公开。 必填项已用*标注