Linux進程管理優化及性能評估工具介紹

衡量Linux CPU使用的指標node

須要關注如下地方:mysql

第一段須要關注的值:linux

·使用率ios

·在用戶空間所消耗的時間百分比nginx

·在系統空間鎖消耗的時間百分比sql

·消耗在IO等待上的時間apache

若是一個主機上有大量的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經常使用系統評估的一些方法,感謝各位看官

相關文章
相關標籤/搜索