1. 程式人生 > >為什麽使能RPS/RFS, 或者RSS/網卡多隊列後,QPS反而下降?

為什麽使能RPS/RFS, 或者RSS/網卡多隊列後,QPS反而下降?

ip協議 pack table 網卡 NPU function 簡單的 數據包 socket

http://laoar.github.io/blog/2017/05/07/rps/

TL;DR

  • RPS
    即receive side steering,利用網卡的多隊列特性,將每個核分別跟網卡的一個首發隊列綁定,以達到網卡硬中斷和軟中斷均衡的負載在各個CPU上。
    他要求網卡必須要支持多隊列特性。

  • RPS
    receive packet steering
    他把收到的packet依據一定的hash規則給hash到不同的CPU上去,以達到各個CPU負載均衡的目的。
    他只是把軟中斷做負載均衡,不去改變硬中斷。因而對網卡沒有任何要求。

  • RFS
    receive flow steering
    RFS需要依賴於RPS,他跟RPS不同的是不再簡單的依據packet來做hash,而是根據flow的特性,即application在哪個核上來運行去做hash,從而使得有更好的數據局部性。

我們可以看到很多案例,使用這些特性後提醒了網絡包的處理能力,從而提升QPS,降低RT。

但是,我們知道,任何一個優化特性都不是普遍適用的,都有他特定的場景來應用。
很多人對此可能會有疑惑,那很多優化功能不是都已經作為默認配置了麽,如果不是普遍適用的,幹嘛還要作為默認配置呢?
其實很簡單,一個優化特性可以作為默認配置,依據我的理解,只需要滿足下面這些特征即可:

  • 對某些場景可以顯著提升性能
  • 對大部分場景無害
  • 對某一部分場景可能會損傷性能

所以Linux的很多配置都是可以靈活配置供選擇的。

下面我們就來看下RPS這些特性在哪些場景下才能發揮作用。

問題描述

業務方在使用KVM虛擬機進行性能壓測時,發現某一個核的softirq占比特別高,如下所示:

1
2
3
4
5
6
7
$ mpstall -L ALL 1
03:44:20 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
03:44:21 PM  all   68.58    0.00   20.70    0.00    0.00    5.49    0.00    0.00    0.00    5.24
03:44:21 PM    0   70.00    0.00   23.00    0.00    0.00    0.00    0.00    0.00    0.00    7.00
03:44:21 PM    1   60.78    0.00   16.67    0.00    0.00   21.57    0.00    0.00    0.00    0.98
03:44:21 PM    2   71.29    0.00   21.78    0.00    0.00    0.00    0.00    0.00    0.00    6.93
03:44:21 PM    3   73.74    0.00   21.21    0.00    0.00    0.00    0.00    0.00    0.00    5.05

一句話解釋:這個kvm虛擬機只有一個網卡,有網絡包到達這個網卡後,它會給某一個cpu(如果沒有設置親和性,這個可以認為是隨機的一個cpu,然後就會一直固定在這個cpu上)發中斷,通知該cpu來處理這個包,然後cpu就會觸發一個軟中斷把該包送到tcp/ip協議棧(對於tcp包而言)裏去處理,該包被放入某一個socket的receive buffer中(如果是一個數據包),軟中斷結束。
%soft就是指的CPU耗在軟中斷處理上的時間。
可以看到核1的%soft很高,其他的核的%soft基本為0.
所以就想著把核1的%soft給均攤下,是否可以提升QPS。
我們想到的方法是網卡多隊列,或者RPS/RFS。用這種手段來把網卡軟中斷給均攤到其他的核上去。

其實,看到前面mpstat的顯示,如果對網卡多隊列,RPS/RFS很熟悉,就會意識到他們在這裏不適用。
可惜理解的不深,交了這次學費。

使能網卡多隊列後,果然是QPS不但沒有提升,反而有下降。
下面就是這次調優交的學費。

為了使描述更清晰(其實是因為我做分析的這個kvm虛擬機上沒有網卡多隊列,但是不影響,導致性能下降的原因是一致的),我們只分析RPS來看下為什麽性能會下降。

RPS的原理概述

  • 基於CentOS-7

技術分享圖片

在這之前,軟中斷只能在硬中斷所在CPU上處理,使用RPS後,網卡軟中斷就可以分發到其他的CPU上去做處理了。

使能RPS後為什麽會導致QPS下降?

如上圖所示,使能了RPS後,會增加一些額外的CPU開銷:

  1. 收到網卡中斷的CPU會向其他CPU發IPI中斷,這體現在CPU的%irq上
  2. 需要處理packet的cpu會收到NET_RX_SOFTIRQ軟中斷,這體現再CPU的%soft上。請註意,RPS並不會減少第一個CPU的軟中斷次數,但是會額外給其他的CPU增加軟中斷。他減少的是第一個CPU的軟中斷的執行時間,即,軟中斷裏不再需要那麽多的時間去走協議棧做包解析,把這個時間給均攤到其他的CPU上去了。

量化對比數據

硬中斷次數的變化

這可以通過/proc/interrupts來觀察

1
$ watch -d -n 1 ‘cat /proc/interrupts‘
  • 使能RPS之後:
    技術分享圖片

  • 使能RPS之前:
    技術分享圖片

可以看到,是能RPS後,增加了很多的Function call interrups,即IPI。
而virtio0-input.0(虛擬網卡產生的中斷,類似於圖中NIC產生的中斷)仍然只發給CPU1.
也可以通過dstat來看整體次數的對比

  • 使能RPS之後:
1
2
3
4
5
6
7
$ dstat 
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw 
 62  23   4   0   0  12|   0     0 |7096k   11M|   0     0 |  49k 2261 
 74  13   4   0   0   9|   0     0 |4003k 6543k|   0     0 |  31k 2004 
 59  22   5   0   0  13|   0  4096B|6710k   10M|   0     0 |  48k 2220
  • 使能RPS之前:
1
2
3
4
5
6
7
8
$ dstat 
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw 
 64  23   6   0   0   7|   0  8192B|7917k   12M|   0     0 |  27k 1922 
 64  22   6   0   0   8|   0     0 |7739k   12M|   0     0 |  26k 2210 
 61  23   9   0   0   7|   0     0 |7397k   11M|   0     0 |  25k 2267 
 94   4   0   0   0   1|   0     0 |1262k

軟中斷次數的變化

這可以通過/proc/softirq來觀察

1
$ watch -d -n 1 ‘cat /proc/softirq‘
  • 使能RPS之前:
    技術分享圖片

  • 使能RPS之後:
    技術分享圖片

可以看到,CPU1上的RX_NET數相差不大比較接近,但是CPU0/2/3上各自都增加了NET_RX.

各個CPU利用率的變化

這可以通過mpstat來觀察

1
$ mpstat -P ALL 1
  • 使能RPS之後
1
2
3
4
5
6
Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
Average:     all   66.21    0.00   17.73    0.00    0.00   11.15    0.00    0.00    0.00    4.91
Average:       0   68.17    0.00   18.33    0.00    0.00    7.67    0.00    0.00    0.00    5.83
Average:       1   60.57    0.00   15.81    0.00    0.00   20.80    0.00    0.00    0.00    2.83
Average:       2   69.95    0.00   19.20    0.00    0.00    7.01    0.00    0.00    0.00    3.84
Average:       3   66.39    0.00   17.64    0.00    0.00    8.99    0.00    0.00    0.00    6.99

  • 使能RPS之前
1
2
3
4
5
6
Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
Average:     all   70.18    0.00   19.28    0.00    0.00    5.86    0.00    0.00    0.00    4.68
Average:       0   73.25    0.00   21.50    0.00    0.00    0.00    0.00    0.00    0.00    5.25
Average:       1   58.85    0.00   14.46    0.00    0.00   23.44    0.00    0.00    0.00    3.24
Average:       2   74.50    0.00   20.00    0.00    0.00    0.00    0.00    0.00    0.00    5.50
Average:       3   74.25    0.00   21.00    0.00    0.00    0.00    0.00    0.00    0.00    4.75

可以看到,整體而言,CPU的%soft增大了很多,%usr下降了一些。
我們知道%usr是衡量用戶態程序性能的一個指標,%usr越高,意味著執行業務代碼的時間就越多。如果%usr下降,那就意味著執行業務代碼的時間變少了,這顯然對於業務性能是一個危險信號。
至於%usr裏面如何來提高業務代碼執行效率,是另外的問題了,不討論。

結論,RPS適用的場景

使能了RPS後,會增加CPU的%soft,如果業務場景本身就是CPU密集的,CPU的負載已經很高了,那麽RPS就會擠壓%usr,即擠壓業務代碼的執行時間,從而導致業務性能下降。

適用場景

RPS如果想要提升業務性能,前提是除了網卡中斷所在的CPU外,其他的CPU都需要有一定的空閑時間,這樣使能RPS才能帶來收益,否則就會帶來額外開銷導致性能下降。
在這個場景下,RPS搭配RFS會帶來更好的收益,不討論。

有沒有更優的解決方案?

答案肯定是有的。

It is a SECRET!

為什麽使能RPS/RFS, 或者RSS/網卡多隊列後,QPS反而下降?