服务器网卡大量并发时候,大家肯定遇到过cpu软中断不均衡情况,都压到cpu0上,其他核的cpu闲着没干活。
比如:lvs服务器,高并发的网站服务器,最容易遇到这种问题。
有2种解决方法:
如果网卡不支持多队列,2.6.21后网卡驱动才支持多队列
判断是否支持多队列
lspci -vvv 如果有MSI-X && Enable+ && TabSize > 1,则该网卡是多队列网卡,否则不支持。
cat enable_rps.sh
其中ffff 是0000-1111 代表cpu个数
#!/bin/bash
# Enable RPS (Receive Packet Steering)
rfc=4096
cc=$(grep -c processor /proc/cpuinfo)
rsfe=$(echo $cc*$rfc | bc)
sysctl -w net.core.rps_sock_flow_entries=$rsfe
for fileRps in $(ls /sys/class/net/eth*/queues/rx-*/rps_cpus)
do
echo ffff > $fileRps
done
for fileRfc in $(ls /sys/class/net/eth*/queues/rx-*/rps_flow_cnt)
do
echo $rfc > $fileRfc
done
tail /sys/class/net/eth*/queues/rx-*/{rps_cpus,rps_flow_cnt}
2.如果网卡支持多队列 #!/bin/bash # setting up irq affinity according to /proc/interrupts # 2008-11-25 Robert Olsson # 2009-02-19 updated by Jesse Brandeburg # # > Dave Miller: # (To get consistent naming in /proc/interrups) # I would suggest that people use something like: # char buf[IFNAMSIZ+6]; # # sprintf(buf, "%s-%s-%d", # netdev->name, # (RX_INTERRUPT ? "rx" : "tx"), # queue->index); # # Assuming a device with two RX and TX queues. # This script will assign: # # eth0-rx-0 CPU0 # eth0-rx-1 CPU1 # eth0-tx-0 CPU0 # eth0-tx-1 CPU1 # set_affinity() { if [ $VEC -ge 32 ] then MASK_FILL="" MASK_ZERO="00000000" let "IDX = $VEC / 32" for ((i=1; i<=$IDX;i++)) do MASK_FILL="${MASK_FILL},${MASK_ZERO}" done let "VEC -= 32 * $IDX" MASK_TMP=$((1<<$VEC)) MASK=`printf "%X%s" $MASK_TMP $MASK_FILL` else MASK_TMP=$((1<<(`expr $VEC + $CORE`))) MASK=`printf "%X" $MASK_TMP` fi printf "%s mask=%s for /proc/irq/%d/smp_affinity\n" $DEV $MASK $IRQ printf "%s" $MASK > /proc/irq/$IRQ/smp_affinity } if [ $# -ne 2 ] ; then echo "Description:" echo " This script attempts to bind each queue of a multi-queue NIC" echo " to the same numbered core, ie tx0|rx0 --> cpu0, tx1|rx1 --> cpu1" echo "usage:" echo " $0 core eth0 [eth1 eth2 eth3]" exit fi CORE=$1 # check for irqbalance running IRQBALANCE_ON=`ps ax | grep -v grep | grep -q irqbalance; echo $?` if [ "$IRQBALANCE_ON" == "0" ] ; then echo " WARNING: irqbalance is running and will" echo " likely override this script's affinitization." echo " Please stop the irqbalance service and/or execute" echo " 'killall irqbalance'" fi # # Set up the desired devices. # shift 1 for DEV in $* do for DIR in rx tx TxRx do MAX=`grep $DEV-$DIR /proc/interrupts | wc -l` if [ "$MAX" == "0" ] ; then MAX=`egrep -i "$DEV:.*$DIR" /proc/interrupts | wc -l` fi if [ "$MAX" == "0" ] ; then echo no $DIR vectors found on $DEV continue fi for VEC in `seq 0 1 $MAX` do IRQ=`cat /proc/interrupts | grep -i $DEV-$DIR-$VEC"$" | cut -d: -f1 | sed "s/ //g"` if [ -n "$IRQ" ]; then set_affinity else IRQ=`cat /proc/interrupts | egrep -i $DEV:v$VEC-$DIR"$" | cut -d: -f1 | sed "s/ //g"` if [ -n "$IRQ" ]; then set_affinity fi fi done done done 转载:https://blog.hackroad.com/operations-engineer/linux_server/6405.html