1. cpu介绍
CPU利用率主要依赖于是什么资源在试图存取.内核调度器将负责调度2种资源种类:线程(单一或者多路)和中断.调度器去定义不同资源的不同优先权.以下列表从优先级高到低排列:
- Interrupts(译注:中断) - 设备通知内核,他们完成一次数据处理的过程.例子,当一块网卡设备递送网络数据包或者一块硬件提供了一次IO 请求.
- Kernel(System) Processes(译注:内核处理过程) - 所有内核处理过程就是控制优先级别.
- User Processes(译注:用户进程) - 这块涉及”userland”.所有软件程序都运行在这个user space.这块在内核调度机制中处于低优先级.
从上面,我们可以看出内核是怎样管理不同资源的.还有几个关键内容需要介绍,以下部分就将介绍context(译注:上下文切换),run queues(译注:运行队列)以及utilization(译注:利用率).
2. 上下文切换
多数现代处理器都能够运行一个进程(单一线程)或者线程.多路超线程处理器有能力运行多个线程.然而,Linux 内核还是把每个处理器核心的双核心芯片作为独立的处理器.比如,以Linux 内核的系统在一个双核心处理器上,是报告显示为两个独立的处理器.
一个标准的Linux 内核可以运行50 至 50,000 的处理线程.在只有一个CPU时,内核将调度并均衡每个进程线程.每个线程都分配一个在处理器中被开销的时间额度.一个线程要么就是获得时间额度或已抢先获得一些具有较高优先级(比如硬件中断),其中较高优先级的线程将从区域重新放置回处理器的队列中.这种线程的转换关系就是我们提到的上下文切换.
每次内核的上下文切换,资源被用于关闭在CPU寄存器中的线程和放置在队列中.系统中越多的上下文切换,在处理器的调度管理下,内核将得到更多的工作.
3. 运行队列
每个CPU 都维护一个线程的运行队列.理论上,调度器应该不断的运行和执行线程.进程线程不是在sleep 状态中(译注:阻塞中和等待IO中)或就是在可运行状态中.如果CPU 子系统处于高负荷下,那就意味着内核调度将无法及时响应系统请求.导致结果,可运行状态进程拥塞在运行队列里.当运行队列越来越巨大,进程线程将花费更多的时间获取被执行.
比较流行的术语就是”load”,它提供当前运行队列的详细状态.系统 load 就是指在CPU 队列中有多少数目的线程,以及其中当前有多少进程线程数目被执行的组合.如果一个双核系统执行了2个线程,还有4个在运行队列中,则 load 应该为 6. top 这个程序里显示的load averages 是指1,5,15 分钟以内的load 情况.
4. CPU利用率
CPU 利用率就是定义CPU 使用的百分比.评估系统最重要的一个度量方式就是CPU 的利用率.多数性能监控工具关于CPU 利用率的分类有以下几种:
- User Time(译注:用户进程时间) - 关于在user space中被执行进程在CPU 开销时间百分比.
- System Time(译注:内核线程以及中断时间) - 关于在kernel space中线程和中断在CPU 开销时间百分比.
- Wait IO(译注:IO 请求等待时间) - 所有进程线程被阻塞等待完成一次IO 请求所占CPU 开销idle的时间百分比.
- Idle(译注:空闲) - 一个完整空闲状态的进程在CPU 处理器中开销的时间百分比.
5. cpu性能监控
理解运行队列,利用率,上下文切换对怎样CPU 性能最优化之间的关系.早期提及到,性能是相对于基准线数据的.在一些系统中,通常预期所达到的性能包括:
-
Run Queues - 每个处理器应该运行队列不超过1-3个线程.例子,一个双核处理器应该运行队列不要超过6 个线程。
-
CPU Utiliation - 如果一个CPU 被充分使用,利用率分类之间均衡的比例应该是:
65% - 70% User Time 30% - 35% System Time 0% - 5% Idle Time
-
Context Switches - 上下文切换的数目直接关系到CPU 的使用率,如果CPU 利用率保持在上述均衡状态时,大量的上下文切换是正常的.
很多Linux 上的工具可以得到这些状态值,首先就是 vmstat 和 top 这2个工具。
6. vmstat的使用
vmstat 工具提供了一种低开销的系统性能观察方式.因为 vmstat 本身就是低开销工具,在非常高负荷的服务器上,你需要查看并监控系统的健康情况,在控制窗口还是能够使用vmstat 输出结果.这个工具运行在2种模式下:average 和 sample 模式.sample 模式通过指定间隔时间测量状态值.这个模式对于理解在持续负荷下的性能表现,很有帮助.下面就是
vmstat 运行1秒间隔的示例:
# vmstat 1 procs ———–memory———- —swap– —–io—- –system– —-cpu—- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 104300 16800 95328 72200 0 0 5 26 7 14 4 1 95 0 0 0 104300 16800 95328 72200 0 0 0 24 1021 64 1 1 98 0 0 0 104300 16800 95328 72200 0 0 0 0 1009 59 1 1 98 0
7. 案例学习:持续的CPU 利用率
在这个例子中,这个系统被充分利用
# vmstat 1 procs memory swap io system cpu r b swpd free buff cache si so bi bo in cs us sy wa id 3 0 206564 15092 80336 176080 0 0 0 0 718 26 81 19 0 0 2 0 206564 14772 80336 176120 0 0 0 0 758 23 96 4 0 0 1 0 206564 14208 80336 176136 0 0 0 0 820 20 96 4 0 0 1 0 206956 13884 79180 175964 0 412 0 2680 1008 80 93 7 0 0 2 0 207348 14448 78800 175576 0 412 0 412 763 70 84 16 0 0 2 0 207348 15756 78800 175424 0 0 0 0 874 25 89 11 0 0 1 0 207348 16368 78800 175596 0 0 0 0 940 24 86 14 0 0 1 0 207348 16600 78800 175604 0 0 0 0 929 27 95 3 0 2 3 0 207348 16976 78548 175876 0 0 0 2508 969 35 93 7 0 0 4 0 207348 16216 78548 175704 0 0 0 0 874 36 93 6 0 1 4 0 207348 16424 78548 175776 0 0 0 0 850 26 77 23 0 0 2 0 207348 17496 78556 175840 0 0 0 0 736 23 83 17 0 0 0 0 207348 17680 78556 175868 0 0 0 0 861 21 91 8 0 1
根据观察值,我们可以得到以下结论:
- 有大量的中断(in) 和较少的上下文切换(cs).这意味着一个单一的进程在产生对硬件设备的请求.
- 进一步显示某单个应用,user time(us)经常在85%或者更多.考虑到较少的上下文切换,这个应用应该还在处理器中被处理.
- 运行队列还在可接受的性能范围内,其中有2个地方,是超出了允许限制.
8. 案例学习:超负荷调度
在这个例子中,内核调度中的上下文切换处于饱和
# vmstat 1 procs memory swap io system cpu r b swpd free buff cache si so bi bo in cs us sy wa id 2 1 207740 98476 81344 180972 0 0 2496 0 900 2883 4 12 57 27 0 1 207740 96448 83304 180984 0 0 1968 328 810 2559 8 9 83 0 0 1 207740 94404 85348 180984 0 0 2044 0 829 2879 9 6 78 7 0 1 207740 92576 87176 180984 0 0 1828 0 689 2088 3 9 78 10 2 0 207740 91300 88452 180984 0 0 1276 0 565 2182 7 6 83 4 3 1 207740 90124 89628 180984 0 0 1176 0 551 2219 2 7 91 0 4 2 207740 89240 90512 180984 0 0 880 520 443 907 22 10 67 0 5 3 207740 88056 91680 180984 0 0 1168 0 628 1248 12 11 77 0 4 2 207740 86852 92880 180984 0 0 1200 0 654 1505 6 7 87 0 6 1 207740 85736 93996 180984 0 0 1116 0 526 1512 5 10 85 0 0 1 207740 84844 94888 180984 0 0 892 0 438 1556 6 4 90 0
根据观察值,我们可以得到以下结论:
- 上下文切换数目高于中断数目,说明kernel中相当数量的时间都开销在上下文切换线程.
- 大量的上下文切换将导致CPU 利用率分类不均衡.很明显实际上等待io 请求的百分比(wa)非常高,以及user time百分比非常低(us).
- 因为CPU 都阻塞在IO请求上,所以运行队列里也有相当数目的可运行状态线程在等待执行.
9. mpstat 工具的使用
如果你的系统运行在多处理器芯片上,你可以使用 mpstat 命令来监控每个独立的芯片.Linux 内核视双核处理器为2 CPU’s,因此一个双核处理器的双内核就报告有4 CPU’s 可用.
mpstat 命令给出的CPU 利用率统计值大致和 vmstat 一致,但是 mpstat 可以给出基于单个处理器的统计值.
# mpstat –P ALL 1 Linux 2.4.21-20.ELsmp (localhost.localdomain) 05/23/200605:17:31 PM CPU %user %nice %system %idle intr/s 05:17:32 PM all 0.00 0.00 3.19 96.53 13.27 05:17:32 PM 0 0.00 0.00 0.00 100.00 0.00 05:17:32 PM 1 1.12 0.00 12.73 86.15 13.27 05:17:32 PM 2 0.00 0.00 0.00 100.00 0.00 05:17:32 PM 3 0.00 0.00 0.00 100.00 0.00
10. 案例学习: 未充分使用的处理量
在这个例子中,为4 CPU核心可用.其中2个CPU 主要处理进程运行(CPU 0 和1).第3个核心处理所有内核和其他系统功能(CPU 3).第4个核心处于idle(CPU 2).
使用 top 命令可以看到有3个进程差不多完全占用了整个CPU 核心.
# top -d 1 top - 23:08:53 up 8:34, 3 users, load average: 0.91, 0.37, 0.13 Tasks: 190 total, 4 running, 186 sleeping, 0 stopped, 0 zombie Cpu(s): 75.2% us, 0.2% sy, 0.0% ni, 24.5% id, 0.0% wa, 0.0% hi, 0.0% si Mem: 2074736k total, 448684k used, 1626052k free, 73756k buffers Swap: 4192956k total, 0k used, 4192956k free, 259044k cachedPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 15957 nobody 25 0 2776 280 224 R 100 20.5 0:25.48 php 15959 mysql 25 0 2256 280 224 R 100 38.2 0:17.78 mysqld 15960 apache 25 0 2416 280 224 R 100 15.7 0:11.20 httpd 15901 root 16 0 2780 1092 800 R 1 0.1 0:01.59 top 1 root 16 0 1780 660 572 S 0 0.0 0:00.64 init# mpstat –P ALL 1 Linux 2.4.21-20.ELsmp (localhost.localdomain) 05/23/200605:17:31 PM CPU %user %nice %system %idle intr/s 05:17:32 PM all 81.52 0.00 18.48 21.17 130.58 05:17:32 PM 0 83.67 0.00 17.35 0.00 115.31 05:17:32 PM 1 80.61 0.00 19.39 0.00 13.27 05:17:32 PM 2 0.00 0.00 16.33 84.66 2.01 05:17:32 PM 3 79.59 0.00 21.43 0.00 0.0005:17:32 PM CPU %user %nice %system %idle intr/s 05:17:33 PM all 85.86 0.00 14.14 25.00 116.49 05:17:33 PM 0 88.66 0.00 12.37 0.00 116.49 05:17:33 PM 1 80.41 0.00 19.59 0.00 0.00 05:17:33 PM 2 0.00 0.00 0.00 100.00 0.00 05:17:33 PM 3 83.51 0.00 16.49 0.00 0.0005:17:33 PM CPU %user %nice %system %idle intr/s 05:17:34 PM all 82.74 0.00 17.26 25.00 115.31 05:17:34 PM 0 85.71 0.00 13.27 0.00 115.31 05:17:34 PM 1 78.57 0.00 21.43 0.00 0.00 05:17:34 PM 2 0.00 0.00 0.00 100.00 0.00 05:17:34 PM 3 92.86 0.00 9.18 0.00 0.0005:17:34 PM CPU %user %nice %system %idle intr/s 05:17:35 PM all 87.50 0.00 12.50 25.00 115.31 05:17:35 PM 0 91.84 0.00 8.16 0.00 114.29 05:17:35 PM 1 90.82 0.00 10.20 0.00 1.02 05:17:35 PM 2 0.00 0.00 0.00 100.00 0.00 05:17:35 PM 3 81.63 0.00 15.31 0.00 0.00
你也可以使用 ps 命令通过查看 PSR 这列,检查哪个进程在占用了哪个CPU.
# while :; do ps -eo pid,ni,pri,pcpu,psr,comm | grep ‘mysqld’; sleep 1; done PID NI PRI %CPU PSR COMMAND 15775 0 15 86.0 3 mysqld PID NI PRI %CPU PSR COMMAND 15775 0 14 94.0 3 mysqld PID NI PRI %CPU PSR COMMAND 15775 0 14 96.6 3 mysqld PID NI PRI %CPU PSR COMMAND 15775 0 14 98.0 3 mysqld PID NI PRI %CPU PSR COMMAND 15775 0 14 98.8 3 mysqld PID NI PRI %CPU PSR COMMAND 15775 0 14 99.3 3 mysqld
结论
监控 CPU 性能由以下几个部分组成:
- 检查system的运行队列,以及确定不要超出每个处理器3个可运行状态线程的限制.
- 确定CPU 利用率中user/system比例维持在70/30
- 当CPU 开销更多的时间在system mode,那就说明已经超负荷并且应该尝试重新调度优先级
- 当I/O 处理得到增长,CPU 范畴的应用处理将受到影响