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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:

衡量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常用系统评估的一些方法,感谢各位看官

 

 

 本文转自zuzhou 51CTO博客,原文链接:http://blog.51cto.com/yijiu/1587056


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5天前
|
存储 Linux API
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?本文带你一探究竟!
【Linux进程概念】—— 操作系统中的“生命体”,计算机里的“多线程”
|
3月前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
127 1
|
18天前
|
存储 网络协议 Linux
【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件
本文详细介绍了Linux中的进程IO与系统调用,包括 `open`、`write`、`read`和 `close`函数及其用法,解释了文件描述符(fd)的概念,并深入探讨了Linux中的“一切皆文件”思想。这种设计极大地简化了系统编程,使得处理不同类型的IO设备变得更加一致和简单。通过本文的学习,您应该能够更好地理解和应用Linux中的进程IO操作,提高系统编程的效率和能力。
66 34
|
6天前
|
缓存 NoSQL Linux
Linux系统内存使用优化技巧
交换空间(Swap)的优化 禁用 Swap sudo swapoff -a 作用:这个命令会禁用系统中所有的 Swap 空间。swapoff 命令用于关闭 Swap 空间,-a 参数表示关闭 /etc/fstab 文件中配置的所有 Swap 空间。 使用场景:在高性能应用场景下,比如数据库服务器或高性能计算服务器,禁用 Swap 可以减少磁盘 I/O,提高系统性能。
26 3
|
22天前
|
消息中间件 Linux C++
c++ linux通过实现独立进程之间的通信和传递字符串 demo
的进程间通信机制,适用于父子进程之间的数据传输。希望本文能帮助您更好地理解和应用Linux管道,提升开发效率。 在实际开发中,除了管道,还可以根据具体需求选择消息队列、共享内存、套接字等其他进程间通信方
59 16
|
2月前
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
160 20
|
3月前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
128 13
|
3月前
|
运维 监控 Linux
BPF及Linux性能调试探索初探
BPF技术从最初的网络数据包过滤发展为强大的系统性能优化工具,无需修改内核代码即可实现实时监控、动态调整和精确分析。本文深入探讨BPF在Linux性能调试中的应用,介绍bpftune和BPF-tools等工具,并通过具体案例展示其优化效果。
122 14
|
3月前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具