背景
網卡與操作系統的交互一般有兩種方式:
- 一種是中斷(IRQ,網卡在收到了網絡信號之後,主動發送中斷到CPU,而CPU將會立即停下手邊的活以便對這個中斷信號進行分析)
- 另一種叫DMA(Direct Memory Access, 也就是允許硬件在無CPU干預的情況下將數據緩存在指定的內存空間內,在CPU合適的時候才處理)
目前在實際生產中,服務器還使用的中斷方式 ,據說DMA方式會使外部設備的控制器獨佔PCI總線,從而CPU無法與外部設備進行交互,這對通用型操作系統Linux來說,是很難接受的,所以DMA方式在Linux內核裏使用得很少。
問題判定
當出現CPU佔用不均的時候,就需要考慮網卡多隊列是否尚未與CPU綁定引起的?
mpstat -P ALL 1
18:20:33 CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
18:20:33 all 0,23 0,00 0,08 0,11 6,41 0,02 0,00 93,16 2149,29
18:20:33 0 0,25 0,00 0,12 0,07 0,01 0,05 0,00 99,49 127,08
18:20:33 1 0,14 0,00 0,03 0,04 0,00 0,00 0,00 99,78 0,00
18:20:33 2 0,23 0,00 0,02 0,03 0,00 0,00 0,00 99,72 0,02
18:20:33 3 0,28 0,00 0,15 0,28 25,63 0,03 0,00 73,64 2022,19
- 查看設備硬件是否支持網卡多隊列
#lspci -vvv
Ethernet controller的條目內容,如果有MSI-X && Enable+ && TabSize > 1,則該網卡是多隊列網卡
- 查看是否打開網卡多隊列
cat /etc/modprobe.conf查看網卡驅動。
broadcom網卡的驅動爲e1000,默認打開網卡多隊列
intel網卡的驅動爲igb,默認不打開網卡多隊列,需要添加options igb RSS=8,8(不同網卡之間的配置用“逗號”隔開)。
cat /proc/interrupt | grep eth,觀察產生了8個網卡對列,並且對應着不同的中斷,即已經打開。
3. 設置中斷親和性:
將中斷52-59分別綁定到CPU0-7上。
echo "1" > /proc/irq/52/smp_affinity
echo "2" > /proc/irq/53/smp_affinity
echo "4" > /proc/irq/54/smp_affinity
echo "8" > /proc/irq/55/smp_affinity
echo "10" > /proc/irq/56/smp_affinity
echo "20" > /proc/irq/57/smp_affinity
echo "40" > /proc/irq/58/smp_affinity
echo "80" > /proc/irq/59/smp_affinity
/proc/irq/${IRQ_NUM}/smp_affinity爲中斷號爲IRQ_NUM的中斷綁定的CPU核的情況。以十六進制表示,每一位代表一個CPU核。
1(00000001)代表CPU0
2(00000010)代表CPU1
3(00000011)代表CPU0和CPU1
當網卡多對列大於32時,需要每8位中間使用“,”分隔,如下所示
00,00000001
00,00000002
00,00000004
00,00000008
00,00000010
00,00000020
00,00000040
注意:
- 使用網卡中斷綁定時,切記需要關閉系統中斷systemctl stop irqbalance
- 生產中虛擬機可能存在無法提供與CPU數目相同的網卡中斷,可以考慮採用系統中斷,啓動命令:
systemctl start irqbalance