SMP irq affinity与RPS/RFS的调优纪实


现象描述:

研发反馈有一批机器的CPU使用率极不均匀,主要集中在前面一半的核上,如下图所示:
(开局一张图,排障全靠蒙...)


SMP irq affinity与RPS/RFS的调优纪实_第1张图片
cpu_usage

问题排查:

一开始怀疑可能是numa设定或者超线程不合理等原因导致的,在网上翻阅了许多资料与Troubleshooting文档后,仍然存在许多疑惑,期间同事也帮忙测试过确定不是numa设定的问题引起的,其实直接看/proc/cpuinfo也能发现0-19的核心是两颗CPU各占一半,基本排除了numa设定不合理或者内存条全插在一边导致另一颗CPU没有使用的问题(双物理核心CPU)。
可能Trobleshooting就是玄学+科学吧,在仍然毫无头绪的时候,我用top命令不断刷新CPU使用情况,忽然发现 %si 软中断的处理几乎都在0-19核上,而后一半核心的 %us 用户态使用率虽然比较低,但时不时也会运作,又通过ps命令验证了该机器上的代码进程没有设置CPU亲和性,于是开始猜测可能是软中断设置不合理引起的,此时又看到了一些类似问题的排障记录后,便开始进一步了解中断并定位问题。

##查看php进程的总数以及在不同核心上的分布情况
ps -eo psr,comm|grep php |wc -l;ps -eo psr,comm|grep php |sort -n|uniq -c
##mpstat可以监控多核系统下的CPU使用率以及处理的中断数量
mpstat -P ALL 1 

References:

  • 进程在多核CPU环境下分布不均导致TCP连接堆积
  • Linux 内核中断内幕
  • Linux软中断不均的调优命令
  • 硬中断和软中断的原理和实现
  • 多队列网卡及网卡中断绑定阐述

问题解决:

在查阅了大量文档并测试验证之后,已可以定位问题在于这批机器没有针对网卡中断做过优化。其实我们的机器在装机时默认都会做一系列的内核参数优化,也包括网卡多队列的亲和性优化,猜测这批机器在加上优化脚本之后没有重启运行脚本(因为该脚本是写在/etc/rc.local里开机运行的,同时发现系统默认网卡多队列只会绑定到CPU前一半的核心上,如该机器40核,默认绑定到0-19,重启了发现脚本是可以正常执行的),在手动运行脚本后,能看到后面的CPU在%us与%si上的使用率明显上升。

network_queues_tune.sh:
#!/bin/bash
# https://github.com/sklochkov/performance-tuner/blob/master/src/network-queues.sh 

cpus=`grep -c processor /proc/cpuinfo`
if [ $cpus -ge 32 ] ; then
    cpus=32
fi
q=`grep -E "eth|em|bond|virtio" /proc/interrupts | awk '{print $1}' | cut -d: -f 1` 

ENTR=$[4096*$cpus]

sysctl net.core.rps_sock_flow_entries=$ENTR >/dev/null 2>&1

if [ $? -gt 0 ] ; then
    echo "Kernel does not support net.core.rps_sock_flow_entries"
    exit 0
fi

k=0
for i in $q ; do
    affinity_mask=`printf "%01X" $[2**($k % $cpus)]`
    echo $affinity_mask > /proc/irq/$i/smp_affinity
    k=$[$k+1]
done

interfaces=`ifconfig | grep -E "^eth|^em|^bond" | awk '{print $1}' | grep -v :`
for t_iface in $interfaces ; do
    if [ -d /sys/class/net/$t_iface/queues ] ; then
        RX=`ls -ld /sys/class/net/$t_iface/queues/rx* 2>/dev/null | wc -l`
        TX=`ls -ld /sys/class/net/$t_iface/queues/tx* 2>/dev/null | wc -l`
        if [ $RX -gt 0 ] ; then
            for i in `seq $RX` ; do
                printf "%01X" $[2**$cpus - 1] > /sys/class/net/$t_iface/queues/rx-$[$i - 1]/rps_cpus
                echo $[$ENTR / $RX] > /sys/class/net/$t_iface/queues/rx-$[$i - 1]/rps_flow_cnt
            done
        fi
        if [ $TX -gt 0 ] ; then
            for i in `seq $TX` ; do
                printf "%01X" $[2**$cpus - 1] > /sys/class/net/$t_iface/queues/tx-$[$i - 1]/xps_cpus
            done
        fi
    fi
done

方案优化:

读完这个脚本之后,发现了两个问题:
1,该脚本只适用于小于32核的机器,而我们现在新采购的机器基本都是40核起步,已不再适用;
2,调研了SMP irq affinity与 rps/rfs的具体作用后,发现它们是Linux内核不同时期的两个产物,目的都是为了优化cpu irq不均的问题以提高系统性能。rps/rfs技术是早期软件层面的一个实现,现在的SMP irq affinity技术完全能满足需求,尤其在CPU计算密集的场景中使用rps/rfs可能还会降低性能,因为中间多了一次性能消耗。
3,针对SMP irq affinity技术,调研并测试了网卡多队列绑定到所有核心随机使用与各队列分别绑定到单独核心两种情况,还是推荐大家绑定不同队列到单独核心,因为完全随机核心的话会出现软中断全集中在cpu 0上面以及某一颗物理核心负载过高的现象,如下图:


SMP irq affinity与RPS/RFS的调优纪实_第2张图片
网卡多队列都绑定到0-39核

重写了一版仅使用SMP irq affinity技术的优化脚本(Python版本) :

#!/usr/bin/env python  
# -*- coding: utf8 -*-


import re
from os import system

interrupts_file = '/proc/interrupts'  

def file_hander(TARGET,VALUE='0'):
    with open(TARGET,'w') as f_hander:
        f_hander.write(VALUE)

def set_irq_affinity():  
    stop_irq_balance = 'service irqbalance stop'    
    system(stop_irq_balance)  
    interrupts_ct = open(interrupts_file)  
    cores_nr = len(interrupts_ct.readline().split()) 
    irq_bit = 0  
    while True:
        inter_line = interrupts_ct.readline()  
        if inter_line == "":  
            break 
        irq_list = inter_line.split()
        if re.findall(r'eth|em|bond|virtio',irq_list[-1]):  
            irq_nr = irq_list[0][:-1]              
            TARGET = '/proc/irq/%s/smp_affinity_list' %(irq_nr)
            VALUE = str(irq_bit)
            file_hander(TARGET,VALUE)  
            irq_bit += 1  
            if irq_bit == cores_nr:
                irq_bit = 0  

if __name__ == '__main__':  
    set_irq_affinity()

References:

  • 多队列网卡RSS与RPS的配置
  • 使用RPS/RFS后,QPS反而下降
  • 网卡软中断调优(这个比较杂)
  • What is IRQ Affinity?
  • SMP irq affinity与RPS/RFS介绍
  • SMP irq affinity与RPS/RFS对比压测数据
  • 绑定中断和开启RPS/RFS

你可能感兴趣的:(SMP irq affinity与RPS/RFS的调优纪实)