密集负载下的网卡中断负载均衡smp affinity及单队列RPS

原文 http://rfyiamcool.blog.51cto.com/1030776/1335700

    简单的说就是,每个硬件设备(如:硬盘、网卡等)都需要和 CPU 有某种形式的通信以便 CPU 及时知道发生了什么事情,这样 CPU 可能就会放下手中的事情去处理应急事件,硬件设备主动打扰 CPU 的现象就是硬件中断。

关于SMP IRQ affinity?

新的内核, Linux改进了分配特定中断到指定的处理器(或处理器组)的功能. 这被称为SMP IRQ affinity, 它可以控制系统如何响应各种硬件事件. 允许你限制或者重新分配服务器的工作负载, 从而让服务器更有效的工作. 以网卡中断为例,在没有设置SMP IRQ affinity时, 所有网卡中断都关联到CPU0, 这导致了CPU0负载过高,而无法有效快速的处理网络数据包,导致了瓶颈。 通过SMP IRQ affinity, 把网卡多个中断分配到多个CPU上,可以分散CPU压力,提高数据处理速度。

irqbalance的一些个介绍

irqbalance 用于优化中断分配,它会自动收集系统数据以分析使用模式,并依据系统负载状况将工作状态置于 Performance mode 或 Power-save mode.处于 Performance mode时irqbalance 会将中断尽可能均匀地分发给各个CPU以充分利用 CPU 多核,提升性能.处于 Power-save mode时,irqbalance 会将中断集中分配给第一个 CPU,以保证其它空闲 CPU 的睡眠时间,降低能耗。

在没有配置SMP IRQ affinity,也没有开启irqbalance的时候~

在配置了SMP IRQ affinity,启动了RPS,关闭irqbalance

在作网络程序的时候, 经常需要了解interrupts和软中断的平衡情况, 需要知道每秒有多少中断发生,发生在哪个cpu上.
Linux下中断来源信息可以从 /proc/interrupts 中了解到~

大家会看到他的频率是一样的,因为我们这边已经开了 irqbalance ,这个东西在负载不大的情况下,是个很不错的服务,他的主要功能是可以合理的调配使用各个CPU核心,特别是对于目前主流多核心的CPU,简单的说就是能够把压力均匀的分配到各个CPU核心上,对提升性能有很大的帮助。

[[email protected] ~]# service irqbalance status
irqbalance (pid  21745) is running...
[[email protected] ~]#

首先我们可以通过访问/proc/cpuinfo的信息查看到cpu的具体信息。

获取eth0网卡的中断irq号,并且赋值给shell变量

关闭irqbalance自动分配服务,好让咱们手动分配中断请求`

/etc/init.d/irqbalance stop

指定CPU来处理对应网卡的中断请求

我这里是选择cpu2来处理这个网卡中断~

这里的4是cpu的16进制表达式

CPU              Binary          oct

CPU 0    00000001         1

CPU 1    00000010         2

CPU 2    00000100         4

CPU 3    00001000         8

这里分享一个脚本,直接算就可以了~

#!/bin/bash
#
echo "统计cpu的16进制"
[ $# -ne 1 ] && echo ‘$1 is Cpu core number’ && exit 1
CCN=$1
echo “Print eth0 affinity”
for((i=0; i<${CCN}; i++))
do
echo ==============================
echo "Cpu Core $i is affinity"
((affinity=(1<<i)))
echo "obase=16;${affinity}" | bc
done

要是cpu是8核心的~

要是16个核心的~

[[email protected] ~]# sh run.sh  16
统计cpu的16进制
“Print eth0 affinity”
==============================
Cpu Core 0 is affinity
1
==============================
Cpu Core 1 is affinity
2
==============================
Cpu Core 2 is affinity
4
==============================
Cpu Core 3 is affinity
8
==============================
Cpu Core 4 is affinity
10
==============================
Cpu Core 5 is affinity
20
==============================
Cpu Core 6 is affinity
40
==============================
Cpu Core 7 is affinity
80
==============================
Cpu Core 8 is affinity
100
==============================
Cpu Core 9 is affinity
200
==============================
Cpu Core 10 is affinity
400
==============================
Cpu Core 11 is affinity
800
==============================
Cpu Core 12 is affinity
1000
==============================
Cpu Core 13 is affinity
2000
==============================
Cpu Core 14 is affinity
4000
==============================
Cpu Core 15 is affinity
8000

然后对于 smp_affinity的配置,根据16进制的cpu数目来算的,你要是输入5的话,那意思就是说  cpu0 和cpu2都参与进去了。

大家还会注意到,目录下还有个 smp_affinity_list ,他是十进制的表达方式

两个配置是相通的,smp_affinity_list使用的是十进制,相比较smp_affinity的十六进制,可读性更好些。

echo 3,8 > /proc/irq/31/smp_affinity_list
echo 0-4 > /proc/irq/31/smp_affinity_list

利用watch查看切换后的效果

[[email protected] ~]# watch -n 2 "cat /proc/interrupts |grep eth"

好了,需要说明的是:

对单队列网卡而言,smp_affinity和smp_affinity_list配置多CPU是没有效果的。这话也不是绝对的,咱们可以用 RPS 来搞定。

该功能主要针对单队列网卡多CPU环境,如网卡支持多队列则可使用SMP irq affinity直接绑定硬中断,要是不支持多队列,那就用RPS解决网络软中断的负载均衡,即单个网卡的软中断分散到多个CPU处理,避免单个CPU负载过大导致性能瓶颈。

如何确定你的网卡支持多队列~

最右面的那些就是多队列的信息了

这个是4队列的~

这个是8队列的~

这里用的机型是IBM x3630 m3

网卡是MSI-X的

事实上在一个大量小包的系统上,irqbalance优化几乎没有效果,而且还使得cpu消耗分配的不均衡,导致机器性能得不到充分的利用,这个时候需要把它给结束掉。然后咱们用手动的方法配置下。

不管怎么说,在同等条件下强烈大家选用多队列的网卡,常见的有Intel的82575、82576,Boardcom的57711等。

多队列网卡是一种技术,最初是用来解决网络IO QoS 问题的,随着网络IO的带宽的不断提升,单核CPU不能完全处满足网卡的需求,通过多队列网卡驱动的支持,将各个队列通过中断绑定到不同的核上。其实用bonding网卡绑定在一定程度也可以做中断负载均衡,两个网卡中断号可以绑定在不同的cpu核心上。

由于RPS只是单纯把数据包均衡到不同的cpu,这个时候如果应用程序所在的cpu和软中断处理的cpu不是同一个,此时对于cpu cache的影响会很大,那么RFS确保应用程序处理的cpu跟软中断处理的cpu是同一个,这样就充分利用cpu的cache.

有两种配置的方法:

把每个队列连到一个cpu上

/proc/sys/net/core/rps_sock_flow_entries 32768
/sys/class/net/eth0/queues/rx-0/rps_cpus 00000001
/sys/class/net/eth0/queues/rx-1/rps_cpus 00000002
/sys/class/net/eth0/queues/rx-2/rps_cpus 00000004
/sys/class/net/eth0/queues/rx-3/rps_cpus 00000008
/sys/class/net/eth0/queues/rx-0/rps_flow_cnt 4096
/sys/class/net/eth0/queues/rx-1/rps_flow_cnt 4096
/sys/class/net/eth0/queues/rx-2/rps_flow_cnt 4096
/sys/class/net/eth0/queues/rx-3/rps_flow_cnt 4096

另一种是推荐的方法:   这个方法在多方面测试下,可以很好的均衡下来。

/sys/class/net/eth0/queues/rx-0/rps_cpus 000000ff
/sys/class/net/eth0/queues/rx-1/rps_cpus 000000ff
/sys/class/net/eth0/queues/rx-2/rps_cpus 000000ff
/sys/class/net/eth0/queues/rx-3/rps_cpus 000000ff
/sys/class/net/eth0/queues/rx-0/rps_flow_cnt 4096
/sys/class/net/eth0/queues/rx-1/rps_flow_cnt 4096
/sys/class/net/eth0/queues/rx-2/rps_flow_cnt 4096
/sys/class/net/eth0/queues/rx-3/rps_flow_cnt 4096
/proc/sys/net/core/rps_sock_flow_entries 32768

总结下:

RPS/RFS主要是针对单队列网卡多CPU环境。虽然有这些虚拟队列的支撑,但是毕竟是软件模拟的。 强烈推荐用支持多队列的网卡。

多队列多重中断的网卡在使用了smp affinity之后也可以再使用该RFS RPS的功能,在这里他更像是个接收方的调解员,最大程度的提高cpu cache。

自己的一些理解,要是有不对的地方,请朋友们喷之 !

这两天会把测试的结果贴上来,6楼的库房停电了,从哥们拿申请了几个R720xd的测试机器都连不上了 ! 

这边的网络测试用的是  netperf ~

tar -xzvf netperf-2.5.0.tar.gz
cd netperf-2.5.0
./configure
make
make install

用法:

根据作用范围的不同,netperf的命令行参数可以分为两大类:全局命令行参数、测试相关的局部参数,两者之间使用--分隔:
Netperf [global options] –-[test-specific options]
其中:
全局命令行参数包括如下选项:
-H host :指定远端运行netserver的server IP地址。
-l testlen:指定测试的时间长度(秒)
-t testname:指定进行的测试类型,包括TCP_STREAM,UDP_STREAM,TCP_RR,TCP_CRR,UDP_RR
测试相关的局部参数包括如下选项:
-s size 设置本地系统的socket发送与接收缓冲大小
-S size 设置远端系统的socket发送与接收缓冲大小
-m size 设置本地系统发送测试分组的大小
-M size 设置远端系统接收测试分组的大小
-D 对本地与远端系统的socket设置TCP_NODELAY选项

102 是请求端,可以看到他的网卡跑满是118M左右。

101是服务端 ~

咱们看看客户端的结果:

1)远端系统(即server)使用大小为229376字节的socket接收缓冲

2)本地系统(即client)使用大小为65507字节的socket发送缓冲

3)测试经历的时间为120秒

4)吞吐量的测试结果为961 Mbits/秒

1)远端系统(即server)使用大小为87380字节的socket接收缓冲

2)本地系统(即client)使用大小为16384字节的socket发送缓冲

3)测试经历的时间为120秒

4)吞吐量的测试结果为941 Mbits/秒

时间: 2024-10-01 02:15:07

密集负载下的网卡中断负载均衡smp affinity及单队列RPS的相关文章

网卡中断负载篇~

网卡中断条件一般为:网卡型号为82576或者其他型号.作用:做网卡中断以优化服务器性能.1.检查命令:lspci |grep Eth2.cat /proc/interrupts |grep eth2以下图片是已做过优化的网卡 中断配置:根据图二查看到的0-7的对应网卡数值进行配置echo "1" >/proc/irq/91/smp_affinityecho "2" >/proc/irq/92/smp_affinityecho "4"

网卡中断负载均衡

http://novoland.github.io/%E7%BD%91%E7%BB%9C/2014/07/26/%E7%BD%91%E5%8D%A1%E4%B8%AD%E6%96%AD%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1.html http://www.simlinux.com/2017/02/28/net-softirq.html https://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-li

Linux 双网卡实现负载均衡(Centos or Ubuntu)

将两张网卡绑定,共用一个IP,实现冗余效果.实际上linux双网卡的绑定模式有7种: mode=0 表示 load balancing (round-robin)为负载均衡方式,两块网卡都工作. mode=1 表示 fault-tolerance (active-backup)提供冗余功能,工作方式是主 从的工作方式,也就是说默认情况下只有一块网卡工作,另一块做备份. mode=2 表示 XOR policy 为平衡策略.此模式提供负载平衡和容错能力 mode=3 表示 broadcast 为广

Linux下利用nginx实现负载均衡

linux下利用nginx实现负载均衡 前提条件: 1,安装好jdk 2,安装好tomcat和nginx(可以参考我前两篇文章) 满足前提条件后,要用nginx实现负载均衡,主要是靠配置nginx的配置文件. 我们要实现的架构图如下: 1.分别部署3个tomcat,端口分别为8080,8081,8082 drwxr-xr-x 9 root root 4096 Mar 11 13:41 tomcat8-8080drwxr-xr-x 9 root root 4096 Mar 11 17:27 tom

Windows/Ubuntu下使用nignx实现负载均衡

Windows/Ubuntu下使用nignx实现负载均衡 一.Ubuntu下实现 1.首先安装nginx服务器 sudo apt-get install nginx 2. Cd /etc/nginx/ Sudo vim sites-avaliables/default ①.在server节点外添加: upstream server_pool  { server 192.168.0.88:80 weight=4 max_fails=2 fail_timeout=30s; server 192.16

ubantu 下 tomcat + nginx 实现负载均衡

在自己的ubantu虚拟机下实现nginx+tomcat负载均衡,自己本地练着玩,挺有意思的,记录下过程. 以下参考了几篇有用的博文: Tomcat+Nginx搭建高性能负载均衡集群  http://blog.csdn.net/wang379275614/article/details/47778201: 在Linux里安装.启动nginx   http://blog.csdn.net/molingduzun123/article/details/51850925:http://www.cnbl

LVS DR模式负载均衡的搭建(单网段)

LVS DR模式负载均衡的搭建(单网段) 实验需要五台虚拟机,都是centos7 客户端 路由器 lvs服务器 172.22.144.188 1接口172.22.144.17 2接口192.168.49.5 172.22.144.17 192.168.49.5 rs1服务器 rs2服务器 192.168.49.3 192.168.49.4 **客户端的配置** vim /etc/sysconfig/nerwork-scripts/ifcfg-ens33 DEVICE=ens33 NAME=ens

使用redis解决tomcat6在nginx负载下多节点共享session问题

使用redis共享tomcat多节点session,需要安装redis.nginx.tomcat6以及用于tomcat存储session到redis的jar包:tomcat-redis-session-manager-1.2-tomcat-6.jar. commons-pool-1.6.jar.jedis-2.1.0.jar等.这些jar包.配置文件及demo程序可以在最后的demo地址中下载. 下面是对tomcat.nginx进行配置及运行: 1.把demo包中的jar包拷贝到tomcat的l

大并发高负载下的PHP-FPM参数调优

大并发高负载下的PHP-FPM参数调优 主要针对PHP在Linux下的参数调优 调整文件描述符限制 # ulimit -n 1000000 # vi /etc/security/limits.conf # Setting Shell Limits for File Descriptors *  soft nofile 1000000 *  hard nofile 1000000 禁止PHP代码文件所在分区的文件系统访问时间更新 # vi /etc/fstab 比如PHP代码所在分区: /dev/