Linux进程管理优化及性能评估工具介绍

来源:互联网 发布:java中super的用法 编辑:程序博客网 时间:2024/06/14 09:25

衡量Linux CPU使用的指标

需要关注以下地方:

第一段需要关注的值:

·使用率

·在用户空间所消耗的时间百分比

·在系统空间锁消耗的时间百分比

·消耗在IO等待上的时间

如果一个主机上有大量的cpu消耗在IO等待上,那么说明IO活动非常频繁,而IO子系统性能非常差。

因此我们看到wite的时间居高不下时,说明IO活动非常频繁的,IO子系统非常差

但如果wite的时间不是特别离谱,一般而言问题都不大

 

第二段需要关注的值:

·空闲时间

·平均负载,CPU等待运行活动队列中等待运行的进程的个数

·可运行的进程数,处于等待状态的进程数,这个数值一般不能超出所有cpu物理核心的10倍,如果超出则意味着CPU性能差

·阻塞进程,一般引起阻塞是由IO调用引起的,IO调用长时间不能得到满足则会引起阻塞,而处于非可中断的状态

·上下文切换的个数

·中断的个数,一旦有IO发生,这个对应的设备则会发起中断请求,中断了CPU正在进行的进程而转而中断处理程序

在任何CPU上如果中断量很大的话也意味着cpu被打断的次数频繁,所以衡量一个cpu是否被频繁打断的话,不仅要衡量context switch还要衡量interrupts

 

 

绑定CPU

如果我们期望某一颗cpu上只运行某一进程

 

以nginx为例:

我们有2个4核的cpu,8个核心,我们可以实现2个核心运行内核线程以及nginx的master进程,而其他6个核心运行worker线程

 

实现绑定

在启动系统时向内核传递参数,手动隔离专用的物理核心,在隔离完成之后手动启动起来了,并且手动去分配这被隔离的6个核心

隔离物理核心并不意味着没有切换,因为有些不是切换而是中断处理,隔离了其他进程但不能隔离这个CPU中断的能力

 

因为我们有8颗物理核心,当任何一个进程的中断,有可能会被8颗中的某1颗所处理,所以可能包括当前已经隔离出的CPU,也就是说只是隔离的进程而没有隔离中断,而我们为了做到绝不处理任何额外的程序,还需要隔离中断

可以明确定义某个中断号的中断只关联到某特定的CPU上,而不中断到已经被隔离出的CPU

 

总结如下:

在启动系统时向内核传递参数,手动隔离专用的物理核心,在隔离完成之后手动启动起来了,并且手动去分配这被隔离的6个核心

还要将隔离出的CPU从中断处理中隔离出来,绑定进程到CPU上

 

如何实现在启动系统时隔离CPU并且在启动之后使用taskset绑定其他进程

在/etc/grub.conf 向内核中传递参数:

isolcpus=cpu number,..cpu number

将隔离出的CPU,后面跟上隔离出来的号码比如8颗CPU,将0和1正常使用,将2到7都隔离出来,于是

isolcpus=2,3,4,..cpu number

这样以来 这些CPU将不再处理了

启动完成后手动将几个worker进程绑定在taskset上,明确说明启动几个线程,完后将从隔离的cpu上脱离出来即可

 

脱离中断处理程序 

明确定义每个中断,只能够运行在哪个CPU上,用来实现将一个irq(中断请求处理),只关联到负责运行在其他cpu上的应用程序,我们被称为cpumask

[root@mysql_node1 ~]#  ls /proc/irq/
0  10  12  14  2   25  4  6  8  default_smp_affinity
1  11  13  15  24  3   5  7  9

查看默认是实现的关联性

[root@mysql_node1 ~]#cat /proc/irq/default_smp_affinity
3

查看第1号中断下所关联的cpu

[root@mysql_node1 ~]# cat /proc/irq/1/smp_affinity
3

这是在第3课cpu上运行的,我们继续看

[root@mysql_node1 ~]# cat /proc/irq/10/smp_affinity
3
[root@mysql_node1 ~]# cat /proc/irq/11/smp_affinity
1

默认情况下可能都会关联到同一CPU上去,而默认我们给的是mask

而这些mask完全可以使用cpu的号码或响应mask值响应定义的,而我们记得这些中断的处理我们必须手动指定专门隔离出来之外的cpu上

 

而我们指定的话直接使用echo就可以了(比如我们指定0号和1号cpu)

[root@mysql_node1 ~]# echo cpu_mask > /proc/irq/<irq_num>/smp_affinity

 

这些操作必须手动进行

 

实现调度器的定义

对于一个系统而言最核心的资源是CPU和内存,因此我们完全可以将一个主机上的所有可能cpu并将其归类到根上,而后将其分资源组,可能每个组里分配不均,资源组织有CPU是不能运行进程的,所以我们还要对其划分内存资源

 

但是注意的是内存是无法分段的,因为内存只有一段

如果真的要跨段访问的话,首先要通知给自己的内存控制器,自己的内存控制器发现不是自己本段内存的,于是向对方内存控制器发送请求,所以我们的周期需要在6次之内才能完成,于是跨段内存访问在numa架构上性能比较差的,所以在很多时候,内核默认策略是每隔1秒钟的时候就重新均衡一次,也就是说在numa结构上一个进程有可能随时被调度到其他CPU上去,那也就意味着跨段内存访问也很常见,为了提高numa架构的性能,应该启用cpu清元性,尽可能不做均衡,除非在不均衡情况非常糟糕的情况下

 

如果资源组有numa这种机制的话,说明每个物理cpu本地都对应都一段物理内存,一般比较常见的是有两个cpu,每个CPU有N个核心的这种方式

 

linux如果使用资源组的机制,那么我们需要使用cpusets这种虚拟文件系统来完成了

简单来讲,我们需要分为2个步骤:

1、划分资源组,并且将资源组内哪些资源划分进来

2、将某个进程绑定到组内,就能实现将实现只能在这个资源组内,尽可能实现本地资源的本地性

 

RHEL6 自带就有其机制,可以自动完成资源组的划分和归派

手动划分资源组:

[root@node3 ~]# mkdir /cgroup

编辑fstab,加入以下参数

cpuset             /cgroup             cpuset  defaults        0 0

 

挂载虚拟文件系统

[root@node3 ~]# mount -a

进入cgroup

[root@node3 ~]# cd /cgroup/
[root@node3 cgroup]# ls
cgroup.event_control             memory_spread_page
cgroup.procs             memory_spread_slab
cpu_exclusive             mems
cpus                      notify_on_release
mem_exclusive             release_agent
mem_hardwall             sched_load_balance
memory_migrate             sched_relax_domain_level
memory_pressure             tasks
memory_pressure_enabled

 

里面会自动生成很多文件,其中有一个为cpus,为归类到根组中的cpu有哪些

[root@node3 cgroup]# cat cpus
0-3

很显然的看到,我们的所有cpu都归类到根组中

 

查看自动归类到根组中的内存资源有哪些

[root@node3 cgroup]#  cat mems
0

很显然,我们不是非一致内存访问结构,所有只有第0段

 

查看关联到此组的所有进程PID

[root@node3 cgroup]# cat tasks
1
2
3

###略###

 

 

我们在这个根组下创建的任何子目录都是一级组,我们来测试一下:

[root@node3 cgroup]# mkdir group{1,2}
[root@node3 cgroup]# ls
cgroup.event_control  memory_pressure_enabled
cgroup.procs          memory_spread_page
cpu_exclusive         memory_spread_slab
cpus                  mems
group1                notify_on_release
group2                release_agent
mem_exclusive         sched_load_balance
mem_hardwall          sched_relax_domain_level
memory_migrate        tasks
memory_pressure

 


[root@node3 cgroup]# ls group1/
cgroup.event_control  memory_spread_page
cgroup.procs          memory_spread_slab
cpu_exclusive         mems
cpus                  notify_on_release
mem_exclusive         sched_load_balance
mem_hardwall          sched_relax_domain_level
memory_migrate        tasks
memory_pressure

 

查看cpus,发现是空的

[root@node3 cgroup]# cat group1/cpus
[root@node3 cgroup]# 

 

将其归类

将某个group归类到某个cpu中

[root@node3 cgroup]# cd group1/
[root@node3 group1]# echo 0 > cpus
[root@node3 group1]# cat cpus
0

 

再归类到mems中

[root@node3 group1]# echo 0 > mems
[root@node3 group1]# cat mems
0

 

然后切换至group2中去 见其归类

[root@node3 group1]# cd ../group2/
[root@node3 group2]# echo 1 > cpus
[root@node3 group2]# echo 0 > mems 

#因为只有第0段内存

 

由此,这两个组分好了,那么查看组2内的任务tasks

[root@node3 group2]# cat tasks
[root@node3 group2]# 

发现文件是空的,因为里面没有任何任务在执行,因此有些时候可以自己实现将某个任务只能运行在某个资源组上

那么我们来查看以下根组的tasks,随便找一个PID,将此PID值能运行在组1上

[root@node3 group2]# more ../tasks 

 

比如将进程httpd只运行在组1上

[root@node3 group2]# ps -aux | grep httpd
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ
apache    2760  0.0  0.5 480180  9836 ?        S    Sep21   0:00 /usr/sbin/httpd
apache    2762  0.0  0.5 480180  9836 ?        S    Sep21   0:00 /usr/sbin/httpd
apache    2765  0.0  0.5 480180  9836 ?        S    Sep21   0:00 /usr/sbin/httpd
apache    2766  0.0  0.5 480180  9836 ?        S    Sep21   0:00 /usr/sbin/httpd
apache    2767  0.0  0.5 480180  9836 ?        S    Sep21   0:00 /usr/sbin/httpd
apache    2768  0.0  0.5 480180  9836 ?        S    Sep21   0:00 /usr/sbin/httpd
apache    2771  0.0  0.5 480180  9836 ?        S    Sep21   0:00 /usr/sbin/httpd
apache    2772  0.0  0.5 480180  9836 ?        S    Sep21   0:00 /usr/sbin/httpd
root     20120  0.0  1.0 480044 20200 ?        Ss   Sep19   0:08 /usr/sbin/httpd
root     20736  0.0  0.0 103256   804 pts/0    R+   16:12   0:00 grep httpd

将2760的进程号定义到组0上去

[root@node3 cgroup]# echo 2760 >  group1/tasks
[root@node3 cgroup]# cat ./group1/tasks
2760

 

那么这个进程只能在组1内,也就是0号CPU运行

[root@node3 cgroup]# ps axo comm,pid,psr  | grep httpd
httpd            2760   0
httpd            2762   2
httpd            2765   3
httpd            2766   1
httpd            2767   0
httpd            2768   3


httpd           21124   0
[root@node3 cgroup]# ps axo comm,pid,psr  | grep httpd
httpd            2760   0
httpd            2762   2
httpd            2765   3
httpd            2766   1
httpd            2767   0


[root@node3 cgroup]# ps axo comm,pid,psr  | grep httpd
httpd            2760   0
httpd            2762   2
httpd            2765   3
httpd            2766   1

一个任务只能关联到一个组中,要在一级组上就不能在根组上,因为不能同时调度

 

那么我们讲进程号2762 绑定到组2的task中,再来观察根组的task

[root@node3 cgroup]# grep 2762 tasks
2762

 

将其绑定到group2,那么之前的group中的tasks内的进程号则会消失

[root@node3 cgroup]# echo 2762 > group2/tasks
[root@node3 cgroup]# grep 2762 tasks
[root@node3 cgroup]# grep 2762 group2/tasks
2762

 

所以说一个任务只能绑定在一个组内

 

控制numa策略

在numa结构上,如果每次都使用手动操作可能是一件非常痛苦的事情,好在numa本身可以实现cpu管理的

numactl使用指定的调度或内存放置策略运行进程,使得可以自动关联一个进程到某个numa资源组中

numactl的使用

在numa结构中,如果频繁手动挂载文件系统,会很麻烦,好在umactl提供了numactl命令手动绑定一个进程到某个资源组上的,一个numa节点包含numa内的所有cpu和本地内存

numactl --show          查看当前情况

numactl --hardware      显示系统中可用的节点清单

numactl --membind       只从指定节点分配内存,明确说明进程绑定到哪一段内存中

numactl --cpunodebind   绑定在多个cpu节点上,每个本地的资源组,有的时候我们允许它在两个节点上使用,这时候可以使用这个参数

numactl --preferred    更加期望运行在哪个节点上

 

CPU亲和性管理进程 numad

使用numa命令管理节点后 numad自动启动为守护进程,并且自动监控保证某些进程只能运行在特定上,numad可对基准性能有50%的提高,要想实现目的,numad会周期性访问/proc/文件系统中的信息,而借此信息实现资源绑定

所以将numad服务启动起来,在numa结构上会提高性能

 

而numa中常用的另外一个命令叫做numastat,主要显示进程运行状态

默认跟踪分类

numa_hit

numa_miss

第一次在此节点运行,之后依然在此节点运行被称为命中,如果第一次在此节点运行,往后被负载均衡到其他节点上运行,意味着所有本地资源无法命中

hit越高,说明提升的性能越好

numa_foreign

等等。。。。。不再一一介绍

 

总结

CPU进程优化思路:

#一定做到CPU切换次数较低,尽可能做到上下文切换次数较低,这样额外的系统性能开销就会减小,那么降低的方法无非是将进程绑定在cpu上

常用的方法:

1.taskset 简单绑定,cpu的亲缘性

2.使用cpuset,cpu内存资源组的概念来实现基于虚拟文件系统的cpu亲缘性绑定

3.在numa体系上使用numa的控制功能

以上都为CPU的亲缘性,只不过使用的手段和途径不同

 

一个最有效的隔离方式是实现开机之后将cpu直接隔离出来,因为绑定之后这个cpu还处于工作状态,它还是需要进行切换的,为了避免切换,可以使用内核参数

通过内核参数:

isolcpus = #

 

其次将中断处理从隔离出来的CPU上玻璃掉使用taskset绑定进程至其专用的cpu

再一就是定义进程的优先级别

 

 

关注磁盘IO活动情况查看:

常用工具

iostat

dstat

 

[root@ip-172-31-21-32 ~]# iostat -x /dev/xvdj 1 5
Linux 2.6.32-431.11.2.el6.x86_64 (ip-172-31-21-32)      09/28/14      _x86_64_     (4 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.76    0.00    2.85    0.07    0.03   84.30

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
xvdj              0.00    69.14    0.00   64.07     0.00  1065.66    16.63     0.51    7.91   0.43   2.74

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           6.53    0.00    2.01    0.00    0.00   91.46

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
xvdj              0.00     0.00    0.00   48.00     0.00   384.00     8.00     0.12    2.60   0.31   1.50

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           3.52    0.00    1.01    0.00    0.00   95.48

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
xvdj              0.00     0.00    0.00   24.00     0.00   192.00     8.00     0.07    2.83   0.33   0.80

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.99    0.00    1.75    0.25    0.00   92.02

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
xvdj              0.00     0.00    0.00   33.00     0.00   264.00     8.00     0.15    4.64   0.24   0.80

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           8.29    0.00    6.28    0.00    0.00   85.43

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
xvdj              0.00     0.00    0.00   25.00     0.00   200.00     8.00     0.07    2.76   0.36   0.90

 

对于繁忙的服务器来讲,读写应该是很大的

如果我们发现%util始终居高不下,意味着IO性能低下

 

 

使用dstat

[root@node3 group1]# dstat
Terminal width too small, trimming output.
----total-cpu-usage---- -dsk/total- -net/total->
usr sys idl wai hiq siq| read  writ| recv  send>
  0   0 100   0   0   0| 838B   10k|   0     0 >
  0   0 100   0   0   0|   0     0 | 652B 1577B>
  0   0 100   0   0   0|   0   984k|  17k   12k>
  0   0 100   0   0   0|   0     0 |3165B 2248B>
  0   0  99   0   0   0|   0   104k|2908B 3347B>
  0   0 100   0   0   0|   0     0 | 732B  615B>
  0   0 100   0   0   0|   0     0 |1552B 2159B>

 

因此我们总结出

iostat 通常使用 -x参数

iostat -x /dev/xxxx 

 

dstat 通常使用 -d -r参数

dstat -d -r

 

还可以使用dstat --top-io 来查看哪个进程最占用IO

[root@node3 group1]# dstat -d -r --top-io
-dsk/total- --io/total- ----most-expensive----
read  writ| read  writ|     i/o process     
838B   10k|0.04  0.79 |init       8038B 1160B
   0     0 |   0     0 |zabbix_serv1041B  556B
   0     0 |   0     0 |zabbix_serv 634B  201B
   0     0 |   0     0 |sshd: root@ 144B  196B
   0   176k|   0  28.0 |mongod        0  8601B
   0    96k|   0  8.00 |mongod        0  8192B
   0     0 |   0     0 |zabbix_serv2494B 1196B

通过这种方式来观测哪个进程最消耗IO

 

以上,为linux常用系统评估的一些方法,感谢各位看官

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝发烧39度怎么办手脚很烫 两岁宝宝吃什么吐什么怎么办 7岁宝宝吃多了吐怎么办 7个月的宝宝大便干燥怎么办 10个月宝宝便秘大便干燥怎么办 一岁半宝宝老是拉糊糊状大便怎么办 外阴部长了一个疙瘩有点痒怎么办 小孩打架被另一个小孩家人告怎么办 德保豆浆机有电但不工作怎么办 刚买的笔记本c盘不足怎么办 qq糖粘在喉咙气管里怎么办 穿上旗袍后感觉后腰处不平整怎么办 机打票给客人给错联怎么办?急 ps修证件照感觉不太立体怎么办 手机百度上下载的文档打不开怎么办 5岁宝宝乘飞机没带证件怎么办 网上订飞机票忘记订儿童票了怎么办 两岁宝宝对牛奶鸡蛋过敏了怎么办 两岁宝宝坐不住好跑怎么办 宝宝两岁多了不愿意坐小马桶怎么办 坐火车小孩拉屎在被子上怎么办 川航飞机票名字错了一个字怎么办 胜战本领怎么看走向战场怎么办 数数字油画你的颜料干了怎么办? 数字油画涂颜料涂错了怎么办 绝地求生模拟器注册已达上限怎么办 孕妇把番茄和虾一起吃了怎么办 4岁宝贝吃了玩具小电池怎么办 微信使用零钱需完善实名信息怎么办 两岁宝宝刷牙不会吐水怎么办 孩子牙龈上长了小牙怎么办 供暖公司未供暖却收取供暖费怎么办 两岁宝宝认知和语言能力低怎么办 蜡笔同步被对方发现删掉的怎么办 微信时间和手机时间不同步怎么办 孩子们家乡爱画美丽的也自己怎么办 娃把豆豆弄进鼻孔了怎么办 20岁了不知道自己该干什么怎么办 遇到一个新手买家恶意拍下怎么办 淘宝卖螃蟹有什么要求美工怎么办 淘宝衣服吊牌剪了想退货怎么办修