1. 程式人生 > >Linux效能優化-中斷

Linux效能優化-中斷

中斷是一種非同步的事件處理機制,可以提高系統的併發處理能力
由於中斷處理程式會打斷其他程序的執行,所以為了減少對正常程序執行排程的影響,中斷處理程式就需要儘可能快的執行,如果中斷本身要做的事情不多,那麼處理起來也不會有太大問題
但如果中斷要處理的事情很多,中斷服務程式就有可能要執行很長時間
特別的,中斷處理程式在響應中斷時,還會臨時關閉中斷,這就會導致上一次中斷處理完成之前,其他中斷都不能影響,也就是說中斷有可能會丟失

系統為了解決中斷程式執行過長和中斷丟失的問題,Linux將中斷處理過程分成了兩個階段,也就是上半部和下半部
1.上半部用來快速處理中斷,它在中斷禁止模式下執行,主要處理跟硬體緊密相關或者時間敏感的工作
2.下半部用來延遲處理上半部未完成的工作,通常以核心執行緒的方式執行


以網絡卡接收資料為例
網絡卡接收到資料包後,會通過硬體中斷的方式,通知核心有新的資料到了,這時核心就應該呼叫中斷處理程式來響應它
對於上半部分來說,要把網絡卡的資料讀到記憶體中,然後更新硬體暫存器的狀態(表示資料已經讀好了),最後再發送一個軟中斷訊號,通知下半部做進一步的處理
下半部被軟中斷訊號喚醒後,需要從記憶體中找到網路資料,再按照網路協議棧,對資料進行逐層解析和處理,直到把它送給應用程式

上半部分直接處理硬體請求,也就是硬體中斷,特點是快速執行
下半部分則是由核心處理,也就是軟中斷,特點是延遲執行
上半部會打斷CPU正在執行的人物,然後立即執行中斷處理程式,而下半部以核心執行緒的方式執行,並且每個CPU都對應一個軟中斷核心執行緒,名字為 ksoftireqd/CPU編號
比如0號CPU對應的軟中斷核心執行緒名字是  ksoftirqd/0
一些核心自定義的事件也屬於軟中斷,比如核心排程和RCU鎖(Read-Copy Update的縮寫,是Linux核心中最常用的鎖之一)


檢視軟中斷和核心執行緒
/proc/softirqs    提供了軟中斷的執行情況
/proc/interrupts  提供了硬中斷的執行情況
 

 

CPU相關的
1.使用率   top,htop,ps
2.平均負載 uptime
3.上下文切換 vmstat,dstat,pidstat -w
4.中斷 vmstat /proc/interrupts,/proc/softirq
5.快取使用率

檢視軟中斷

cat /proc/softirqs | awk '{print $1 "          " $2 "               " $ 42}' 
CPU0          CPU1               CPU41
HI:          0               0
TIMER:          2118204662               0
NET_TX:          2925               0
NET_RX:          29401215               0
BLOCK:          1421758               0
BLOCK_IOPOLL:          0               0
TASKLET:          120716               0
SCHED:          701921513               0
HRTIMER:          583842               0
RCU:          2414832320               0

網絡卡大流量匯入匯出資料的時候,發現是
TIMER,SCHED,RCU 在不斷變化


對於硬體中斷

cat /proc/interrupts | awk '{print $1 "          " $2 "               " $ 42}' 
CPU0          CPU1               
0:          294               IR-IO-APIC-edge
..
9:          0               IR-IO-APIC-fasteoi
..
73:          0               DMAR_MSI-edge
74:          121542          IR-HPET_MSI-edge
...
90:          804553               IR-PCI-MSI-edge
...
NMI:          688718               Non-maskable
LOC:          2272539373               Local
SPU:          0               Spurious
PMI:          688718               Performance
IWI:          0               IRQ
RES:          56034546               Rescheduling
CAL:          168951               Function
TLB:          373775272               TLB
TRM:          0               Thermal
THR:          0               Threshold
MCE:          0               Machine
MCP:          121529               Machine
ERR:          0               
MIS:          0   

LOC              每秒都在不斷變化
Non-maskable     1-2秒增加一次
Rescheduling     每秒在不斷變化
TLB              每秒在不斷變化

 

在檢視/proc/softirqs 檔案內容時需要注意
1.注意中斷型別,比如軟中斷中NET_RX表示網路接收中斷,NET_TX表示網路傳送中斷
2.注意同一種中斷在不同CPU上的分佈情況,也就是同一行的內容,在正常情況下,同一種中斷在不同
   CPU上的累積次數英國差不多
但TASKLET在不同的CPU上分佈並不均勻,TASKLET是最常用的軟中斷實現機制,每個TASKLET只執行一次就會結束,並且只在呼叫它的函式所在的CPU上執行
所以TASKLET也會存在一些問題,比如說由於只在一個CPU上執行導致的排程不均衡,再比如不能在多個CPU上並行執行帶來了效能限制

軟中斷是以核心執行緒的方式執行的,每個CPU都會對應一個軟中斷核心執行緒,這個軟中斷核心執行緒叫做
ksoftirqd/CPU編號,ps 檢視如下

ps aux |grep ksoftirqd
root         3  0.0  0.0      0     0 ?        S    Dec06   0:02 [ksoftirqd/0]
root     11195  0.0  0.0 112660   976 pts/0    R+   20:56   0:00 grep --color=auto ksoftirqd

 

 

用hping3模擬 SYN FLOOD攻擊導致的軟中斷上升情況

hping3 -i u1000 --syn 47.93.18.8 --destport 12345 

//用 python -m 開啟一個http服務

top檢視程序負載情況,軟中斷升高了,機器略卡,ksoftirqd 程序使用率也略微上升,說明軟中斷在影響機器

top - 22:02:55 up 13 days,  8:51,  8 users,  load average: 0.00, 0.01, 0.05
Tasks:  82 total,   2 running,  80 sleeping,   0 stopped,   0 zombie
%Cpu(s):  1.7 us,  3.7 sy,  0.0 ni, 88.5 id,  0.0 wa,  0.0 hi,  6.1 si,  0.0 st
KiB Mem :  1016092 total,    94256 free,   107572 used,   814264 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   723248 avail Mem 

檢視 軟中斷情況

watch -d cat /proc/softirqs

                    CPU0
          HI:          6
       TIMER:   25174374
      NET_TX:         25
      NET_RX:    2309211
       BLOCK:     564149
BLOCK_IOPOLL:          0
     TASKLET:         57
       SCHED:          0
     HRTIMER:          0
         RCU:   12226717

TIMER,NET_RX,RCU 這幾個值都有變化,其中NET_RX變化最快,說明是網絡卡接收了很多資料包

用sar看網路流量

//man sar 檢視 DEV 結果如下
       -n { keyword [,...] | ALL }
              Report network statistics.
              Possible keywords are DEV, EDEV, NFS, NFSD, SOCK, IP, EIP, ICMP, EICMP, TCP, ETCP, UDP, SOCK6, IP6, EIP6, ICMP6, EICMP6 and UDP6.
              With the DEV keyword, statistics from the network devices are reported.  The following values are displayed:

IFACE
    Name of the network interface for which statistics are reported.
rxpck/s
    Total number of packets received per second.
txpck/s
    Total number of packets transmitted per second.
rxkB/s
    Total number of kilobytes received per second.
txkB/s
    Total number of kilobytes transmitted per second.
rxcmp/s
    Number of compressed packets received per second (for cslip etc.).
txcmp/s
    Number of compressed packets transmitted per second.
rxmcst/s
    Number of multicast packets received per second.


//執行命令
sar -n DEV 1

10:08:11 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
10:08:12 PM      eth0   2919.19   2925.25    158.02    195.34      0.00      0.00      0.00
10:08:12 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
10:08:12 PM   docker0      0.00      0.00      0.00      0.00      0.00      0.00      0.00

10:08:12 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
10:08:13 PM      eth0   2984.54   2990.72    161.72    211.49      0.00      0.00      0.00
10:08:13 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
10:08:13 PM   docker0      0.00      0.00      0.00      0.00      0.00      0.00      0.00

看第一次輸出的,rxpck/s,就是每秒接收了2919個數據包
rxkb/s,是每秒收到的資料包大小為158K
158*1024/2919.0,每個資料包大概55位元組,說明是大量的小包

 

用tcpdump 分析下對應的埠,一大堆的SYN包,可以確定就是SYN FLOOD導致的

tcpdump port 12345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
22:13:54.082215 IP A > B: Flags [S], seq 17057880, win 512, length 0
22:13:54.082249 IP B > A: Flags [S.], seq 2134046664, ack 77687439, win 29200, options [mss 1460], length 0
22:13:54.082259 IP A > B: Flags [R], seq 77687439, win 0, length 0
22:13:54.082510 IP B > A: Flags [R], seq 559655664, win 0, length 0
22:13:54.083072 IP B > A: Flags [R], seq 77687439, win 0, length 0
22:13:54.083079 IP A > B: Flags [S], seq 17057880, win 512, length 0
22:13:54.083094 IP B > A: Flags [S.], seq 2374986, ack 17057881, win 29200, options [mss 1460], length 0
。。。

SYN FLOOD 問題最簡單的解決方法,就是從交換機或硬體防火牆中封掉源IP,這樣SYN FLOOD網路幀就不會發送到伺服器中了
軟中斷CPU使用率(softirq)升高是一種很常見的效能問題,雖然軟中斷的型別很多,但實際生產中,我們遇到的效能瓶頸大多是網路收發型別的軟中斷,特別是網路接收的軟中斷
藉助sar,tcpdump可以做進一步的分析

 

 

參考

hping3的主頁

hping3的github地址

perf tool