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


现象描述:

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


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:

问题解决:

在查阅了大量文档并测试验证之后,已可以定位问题在于这批机器没有针对网卡中断做过优化。其实我们的机器在装机时默认都会做一系列的内核参数优化,也包括网卡多队列的亲和性优化,猜测这批机器在加上优化脚本之后没有重启运行脚本(因为该脚本是写在/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上面以及某一颗物理核心负载过高的现象,如下图:


网卡多队列都绑定到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:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,273评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,349评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,709评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,520评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,515评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,158评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,755评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,660评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,203评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,287评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,427评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,122评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,801评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,272评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,393评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,808评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,440评论 2 359