-
2019-10-30 22:19:24
1、关于多队列网卡
通过lspci方式查看网卡信息,如果有MSI-X, Enable+ 并且Count > 1,则该网卡是多队列网卡,多队列网卡内部会有多个 Ring Buffer。
[root@localhost ~]# lspci -vvv | grep -A50 "Ethernet controller" | grep -E "Capabilities|Ethernet controller" 01:00.0 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01) Capabilities: [40] Power Management version 3 Capabilities: [50] MSI: Enable- Count=1/1 Maskable+ 64bit+ Capabilities: [70] MSI-X: Enable+ Count=10 Masked- Capabilities: [a0] Express (v2) Endpoint, MSI 00 Capabilities: [e0] Vital Product Data
从以上信息可见,我们的这张网卡是支持多队列的。
2、网卡支持最大队列数及当前使用队列
我们可以通过ethtool命令查看网卡支持的最大队列数,
[root@localhost ~]# ethtool -l eth0 Channel parameters for eth0: Pre-set maximums: RX: 0 TX: 0 Other: 1 Combined: 63 Current hardware settings: RX: 0 TX: 0 Other: 1 Combined: 40
由上可见,该网卡最多支持63个队列,当前使用了40个队列。为什么不开启63个队列呢,因为机器的CPU数没那么多,
[root@localhost ~]# cat /proc/cpuinfo | grep processor | wc -l 40
我们开启多队列的初衷就是为了利用多核。队列数和CPU相等,正好可以每个CPU处理一个队列,这样效率比较高。
3、修改网卡队列数
有时候网卡支持多队列却没有开启,那么就要手动设置网卡队列数,
ethtool -L eth0 combined 8
其中combined指的是网卡收发队列共用的情况,有些网卡可单独设置收发队列,
ethtool -L eth0 rx 8 ethtool -L eth0 tx 8
设置后可以在/sys/class/net/eth0/queues/目录下看到对应的队列,
[root@localhost ~]# cd /sys/class/net/eth0/queues/ [root@localhost queues]# ls rx-0 rx-2 rx-4 rx-6 tx-0 tx-2 tx-4 tx-6 rx-1 rx-3 rx-5 rx-7 tx-1 tx-3 tx-5 tx-7
4、多队列网卡绑核
为了保证CPU均衡,也即是网卡中断能分配到各个CPU,我们通常会将网卡中断绑核,具体操作见——网卡中断均衡设置
5、单队列网卡
上面说的都是多队列网卡,那单队列的怎么搞呢,不能厚此薄彼吧。这时候就出现RPS和RFS了。简单来说就是在软件层面模拟多队列的情况,从而达到CPU均衡。
RPS(Receive Packet Steering)把软中断的负载均衡到各个cpu,是在单个CPU将数据从Ring Buffer取出来之后开始工作,网卡驱动通过四元组(SIP,SPORT,DIP,DPORT)生成一个hash值,然后根据这个hash值分配到对应的CPU上处理,从而发挥多核的能力。
但是还有个问题,由于RPS只是把数据包均衡到不同的cpu,但是收包的应用程序和软中断处理不一定是在同一个CPU,这样对于cpu cache的影响会很大。因此就出现RFS(Receive flow steering),它确保应用程序和软中断处理的cpu是同一个,从而能充分利用cpu的cache,这两个补丁往往都是一起设置,以达到最好的优化效果。
6、设置RPS
首先内核要开启CONFIG_RPS编译选项,然后设置需要将中断分配到哪些CPU,
/sys/class/net/<dev>/queues/rx-<n>/rps_cpus
比如,要将eth0上0号收包软中断均匀分配到64个CPU上(假设机器上有这么多CPU),那么可以如下操作,
echo "ffffffff,ffffffff" > /sys/class/net/eth0/queues/rx-0/rps_cpus
和多队列中断绑定规则类似,每个CPU用1位表示,因此1,2,4,8分别对应0-3号CPU,分配到这些CPU,相加就是15,即f。
如果只想分配到前32个CPU,则可以如下操作,
echo "00000000,ffffffff" > /sys/class/net/eth0/queues/rx-0/rps_cpus
7、设置RFS
上面我们说过RPS和RFS一般要配合使用,效果才最优,因此RFS同样需要开启CONFIG_RPS编译选项,同时设置每个队列的数据流表总数才能真正生效。
这里我们了解一下RFS的细节:
RFS的实现需要依赖两个表——全局socket流表(rps_sock_flow_table)和设备流表(rps_dev_flow_table)。全局socket流表记录的是每个流由上面RPS计算通过hash分配的CPU号,也就是期望的CPU号;设备流表存在于每个网络设备的每个接收队列,表中记录的是每个未完成流使用的CPU号,也就是当前流使用的CPU号。具体使用哪个CPU简单来说有以下规则,
- 如果两个表中记录的对应流使用的是同一个CPU号,就使用这个CPU
- 如果当前流使用的CPU未设置或者CPU处于离线状态,那就使用期望CPU表中的CPU号,也就是RPS计算而得的CPU号
- 如果两个表中对应流记录的CPU核不是同一个:
- a)如果同一流的前一段数据包未处理完,为了避免乱序,不更换CPU,继续使用当前流使用的CPU号
- b)如果同一流的前一段数据包已经处理完,那就可以使用期望CPU表中的CPU号
因此我们需要设置这两个表中记录的entry,对于全局socket流表(rps_sock_flow_table),该配置接口是
/proc/sys/net/core/rps_sock_flow_entries
而设备流表(rps_dev_flow_table)则通过以下接口设置,
/sys/class/net/<dev>/queues/rx-<n>/rps_flow_cnt
两者的关系如下,
rps_sock_flow_entries = rps_flow_cnt * N
其中,N就是队列数量。因此,对于单队列网卡,两个值是一样的。
8、XPS(Transmit Packet Steering)
上面说的都是关于接收队列,那对于发送队列呢,这就需要用到XPS了。
XPS通过创建CPU到网卡发送队列的对应关系,来保证处理发送软中断请求的CPU和向外发送数据包的CPU是同一个CPU,用来保证发送数据包时候的局部性。
对于发送队列到CPU的映射有两种选择:
1、使用CPU映射
这种方式是通过指定发送队列在某几个CPU上处理,通过减小分发的CPU范围来减少锁开销以及cache miss。最常见的就是1对1,和上面说到的接收软中断绑核类似,通过以下接口设置,/sys/class/net/<dev>/queues/tx-<n>/xps_cpus
同样是bitmaps方式。
2、接收队列映射方式
这种方式基于接收队列的映射来选择CPU,也就是说让接收队列和发送队列在同一个CPU,或指定范围的几个CPU来处理。这种方式对于多线程一直收发包的系统效果比较明显,收发包队列处理在同一个CPU,不仅减少了对其他CPU的打断,同时提高应用处理效率,收完包后直接在同个CPU继续发包,从而减小CPU消耗,同时减小包的时延。这种方式映射,可通过一下接口设置(不是所有网卡都支持),
/sys/class/net/<dev>/queues/tx-<n>/xps_rxqs
另外,XPS对于单发送队列网卡没有效果,这个可想而知。
参考资料:
1、https://www.kernel.org/doc/Documentation/networking/scaling.txt更多相关内容 -
单/多队列网卡的前世今生
2021-08-13 15:45:27多队列网卡是一种技术,最初是用来解决网络IO QoS(quality of service)问题的,后来随着网络IO的带宽的不断提升,单核CPU不能完全处满足网卡的需求,通过多队列网卡驱动的支持,将各个队列通过中断绑定到不同的核...多队列网卡是一种技术,最初是用来解决网络IO QoS (quality of service)问题的,后来随着网络IO的带宽的不断提升,单核CPU不能完全处满足网卡的需求,通过多队列网卡驱动的支持,将各个队列通过中断绑定到不同的核上,以满足网卡的需求。
常见的有Intel的82575、82576,Boardcom的57711等,下面以公司的服务器使用较多的Intel 82575网卡为例,分析一下多队列网卡的硬件的实现以及linux内核软件的支持。
1.多队列网卡硬件实现
图1.1是Intel 82575硬件逻辑图,有四个硬件队列。当收到报文时,通过hash包头的SIP、Sport、DIP、Dport四元组,将一条流总是收到相同的队列。同时触发与该队列绑定的中断。
2. 2.6.21以前网卡驱动实现
kernel从2.6.21之前不支持多队列特性,一个网卡只能申请一个中断号,因此同一个时刻只有一个核在处理网卡收到的包。如图2.1,协议栈通过NAPI轮询收取各个硬件queue中的报文到图2.2的net_device数据结构中,通过QDisc队列将报文发送到网卡。
3. 2.6.21后网卡驱动实现
2.6.21开始支持多队列特性,当网卡驱动加载时,通过获取的网卡型号,得到网卡的硬件queue的数量,并结合CPU核的数量,最终通过Sum=Min(网卡queue,CPU core)得出所要激活的网卡queue数量(Sum),并申请Sum个中断号,分配给激活的各个queue。
如图3.1,当某个queue收到报文时,触发相应的中断,收到中断的核,将该任务加入到协议栈负责收包的该核的NET_RX_SOFTIRQ队列中(NET_RX_SOFTIRQ在每个核上都有一个实例),在NET_RX_SOFTIRQ中,调用NAPI的收包接口,将报文收到CPU中如图3.2的有多个netdev_queue的net_device数据结构中。
这样,CPU的各个核可以并发的收包,就不会应为一个核不能满足需求,导致网络IO性能下降。
4.中断绑定
当CPU可以并行收包时,就会出现不同的核收取了同一个queue的报文,这就会产生报文乱序的问题,解决方法是将一个queue的中断绑定到唯一的一个核上去,从而避免了乱序问题。同时如果网络流量大的时候,可以将软中断均匀的分散到各个核上,避免CPU成为瓶颈。
5.中断亲合纠正
一些多队列网卡驱动实现的不是太好,在初始化后会出现图4.1中同一个队列的tx、rx中断绑定到不同核上的问题,这样数据在core0与core1之间流动,导致核间数据交互加大,cache命中率降低,降低了效率。
linux network子系统的负责人David Miller提供了一个脚本,首先检索/proc/interrupts文件中的信息,按照图5.1中eth0-rx-0($VEC)中的VEC得出中断MASK,并将MASK写入中断号53对应的smp_affinity中。
由于eth-rx-0与eth-tx-0的VEC相同,实现同一个queue的tx与rx中断绑定到一个核上,如图所示。
set_irq_affinity脚本位于http://mirror.oa.com/tlinux/tools/set_irq_affinity.sh。
6.多队列网卡识别
#lspci -vvv
Ethernet controller的条目内容,如果有MSI-X && Enable+ && TabSize > 1,则该网卡是多队列网卡。
Message Signaled Interrupts(MSI)是PCI规范的一个实现,可以突破CPU 256条interrupt的限制,使每个设备具有多个中断线变成可能,多队列网卡驱动给每个queue申请了MSI。MSI-X是MSI数组,Enable+指使能,TabSize是数组大小。
-
dpdk预备学习环境准备之多队列网卡认识及测试
2021-11-29 16:50:39dpdk学习预备之多队列网卡环境搭建 dpdk学习预备之环境搭建: 这里使用VMware+ubuntu虚拟机环境 这里涉及到的小知识点: 1:配置多个网卡,并使环境上多个网卡都能生效。 2:修改虚拟机网卡名称为传统的eth0...dpdk学习预备之多队列网卡环境搭建
dpdk学习预备之环境搭建: 这里使用VMware+ubuntu虚拟机环境
这里涉及到的小知识点:
1:配置多个网卡,并使环境上多个网卡都能生效。
2:修改虚拟机网卡名称为传统的eth0
3:多队列网卡的测试
dpdk测试环境是怎样的?
个人理解:网卡一般接收到数据后会给内核相关内核协议栈,这里dpdk会代替这里的协议栈,接管网卡上的数据,实现定制性开发,对网络性能进行优化与提升。
所以:
1:dpdk要接管一个网卡上的数据,所以我们测试的时候需要专门提供一个网卡(可以是虚拟的)进行dpdk的测试。
2:dpdk环境要支持多队列网卡,如何配置环境多队列网卡?3:dpdk源码编译,配置,测试等(这个后期实现)
配置环境支持多个网卡
1:在vmware环境中对应虚拟机的虚拟机设置中,增加网络适配器(一个或者多个),对应网卡的个数。
2:启动虚拟机,查看网卡信息:
当前生效的只有一个网卡,是桥接模式的第一个网卡:
ubuntu@ubuntu:~$ ifconfig ens33 Link encap:Ethernet HWaddr 00:0c:29:b2:2f:c4 inet addr:192.168.50.56 Bcast:192.168.50.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:feb2:2fc4/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1636 errors:0 dropped:0 overruns:0 frame:0 TX packets:122 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:120640 (120.6 KB) TX bytes:15158 (15.1 KB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:160 errors:0 dropped:0 overruns:0 frame:0 TX packets:160 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:11840 (11.8 KB) TX bytes:11840 (11.8 KB)
但是实际上我们已经配置了三个网卡,并且都在环境中:
ubuntu@ubuntu:~$ ifconfig -a ens33 Link encap:Ethernet HWaddr 00:0c:29:b2:2f:c4 inet addr:192.168.50.56 Bcast:192.168.50.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:feb2:2fc4/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:2240 errors:0 dropped:0 overruns:0 frame:0 TX packets:167 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:164047 (164.0 KB) TX bytes:20750 (20.7 KB) ens38 Link encap:Ethernet HWaddr 00:0c:29:b2:2f:ce BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) ens39 Link encap:Ethernet HWaddr 00:0c:29:b2:2f:d8 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:160 errors:0 dropped:0 overruns:0 frame:0 TX packets:160 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:11840 (11.8 KB) TX bytes:11840 (11.8 KB)
3:配置使多个网卡都能生效。
修改 /etc/network/interfaces,参考默认的一个网卡,增加其他没有增加的网卡
ubuntu@ubuntu:~$ sudo vim /etc/network/interfaces ubuntu@ubuntu:~$ cat /etc/network/interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback # The primary network interface auto ens33 iface ens33 inet dhcp #这里以下:是我对应环境新增的 auto ens38 iface ens38 inet dhcp auto ens39 iface ens39 inet dhcp ubuntu@ubuntu:~$ service networking restart #重启了网络服务
4:查看网卡信息并进行测试。
重启网络服务,并查看当前生效网卡的情况: 发现多个网卡,都已经生效了。
ubuntu@ubuntu:~$ service networking restart #不同的linux环境重启网络命令是不同的 ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units === Authentication is required to restart 'networking.service'. Authenticating as: ubuntu,,, (ubuntu) Password: ==== AUTHENTICATION COMPLETE === ubuntu@ubuntu:~$ ifconfig ens33 Link encap:Ethernet HWaddr 00:0c:29:b2:2f:c4 inet addr:192.168.50.56 Bcast:192.168.50.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:feb2:2fc4/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:7546 errors:0 dropped:0 overruns:0 frame:0 TX packets:524 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:563423 (563.4 KB) TX bytes:86418 (86.4 KB) ens38 Link encap:Ethernet HWaddr 00:0c:29:b2:2f:ce inet addr:192.168.11.155 Bcast:192.168.11.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:feb2:2fce/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:14 errors:0 dropped:0 overruns:0 frame:0 TX packets:14 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1976 (1.9 KB) TX bytes:1566 (1.5 KB) ens39 Link encap:Ethernet HWaddr 00:0c:29:b2:2f:d8 inet addr:192.168.11.156 Bcast:192.168.11.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:feb2:2fd8/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:7 errors:0 dropped:0 overruns:0 frame:0 TX packets:9 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:986 (986.0 B) TX bytes:1262 (1.2 KB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:160 errors:0 dropped:0 overruns:0 frame:0 TX packets:160 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:11840 (11.8 KB) TX bytes:11840 (11.8 KB)
网卡名称修改为eth0 …,可参考上一步改为多网卡
描述:发现网卡的命名是ens33, 不是eth0
(网络上有说eth0是物理网卡命名,ens33是虚拟网卡命名,代表不同的网卡特性,这个是可以配置修改的)
1:修改命名规则,改为eth0 …
修改配置文件/etc/default/grub,在配置文件中”GRUB_CMDLINE_LINUX“字段对应值新增:net.ifnames=0 biosdevname=0
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0" #这里只新增net.ifnames=0 biosdevname=0 字段,如果有其他,保留就好
2:执行命令:update-grub
ubuntu@ubuntu:~$ sudo update-grub [sudo] password for ubuntu: Generating grub configuration file ... Found linux image: /boot/vmlinuz-4.4.0-206-generic Found initrd image: /boot/initrd.img-4.4.0-206-generic Found linux image: /boot/vmlinuz-4.4.0-186-generic Found initrd image: /boot/initrd.img-4.4.0-186-generic done
3:查看是否生效,用ifconfig /ifconfig -a
注:如果没有生效,观察配置文件**/etc/network/interfaces**中相关配置,修改完对应的网卡后,重启网络服务,并查看
ubuntu@ubuntu:~$ ifconfig eth0 Link encap:Ethernet HWaddr 00:0c:29:5c:4d:0c inet addr:192.168.11.138 Bcast:192.168.11.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:fe5c:4d0c/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:176 errors:0 dropped:0 overruns:0 frame:0 TX packets:180 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:16619 (16.6 KB) TX bytes:26760 (26.7 KB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:576 errors:0 dropped:0 overruns:0 frame:0 TX packets:576 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:44256 (44.2 KB) TX bytes:44256 (44.2 KB)
4:eth配置多网卡,可以参考上文
5:不同的ubuntu环境可能有差异。(ubuntu20 修改网卡配置文件为/etc/netplan/00-installer-config.yaml)
1: 修改grub配置文件/etc/default/grub,在GRUB_CMDLINE_LINUX对应字段中增加: net.ifnames=0 biosdevname=0 2: 修改使环境识别eth,一般修改的是文件/etc/network/interfaces,参考其中默认的,在对应的网卡中,修改或者增加其他网卡配置。 ubuntu20环境中修改/etc/netplan/00-installer-config.yaml,用命令 sed -i "s/ens32/eth0/" /etc/netplan/00-installer-config.yaml 注意,其中的ens32为00-installer-config.yaml文件中对应的网卡字符,可能是其他。 3: 执行sudo update-grub 4: 重启环境进行查看
配置网卡支持多队列
简单理解:就是网卡的DMA队列有多个,有自己对队列的分配机制。
1:修改虚拟机配置,使支持多队列
主要修改的是vmware工具上我们安装的虚拟机的配置文件:
1:修改虚拟机配置,处理器个数增加一点(方便观察),这里我设为4
2:再对应虚拟机目录中的“Ubuntu 64 位.vmx”(这是我的配置文件),用编辑器打开,修改要配置多队列网卡的网卡配置,这里修改的是
注意:最好在关闭虚拟机的状态下修改
#在Ubuntu 64 位.vmx 中打开,修改ethernet1配置,把e1000 改为 vmxnet3 #如果没有wakeOnPcktRcv 增加就好 #这里我的ethernet1 对应的是环境上的eth0 ethernet1.virtualDev = "vmxnet3" ethernet1.wakeOnPcktRcv = "TRUE"
2:查看是否支持多队列网卡
1:使用cat /proc/interrupts 命令可以查看多队列网卡的效果。
ubuntu@ubuntu:~$ cat /proc/interrupts |grep eth0 57: 13 0 4 0 PCI-MSI 1572864-edge eth0-rxtx-0 58: 2 0 0 0 PCI-MSI 1572865-edge eth0-rxtx-1 59: 6 0 0 0 PCI-MSI 1572866-edge eth0-rxtx-2 60: 0 0 0 0 PCI-MSI 1572867-edge eth0-rxtx-3 61: 0 0 0 0 PCI-MSI 1572868-edge eth0-event-4
可以看到,配置了4个处理器,这里的队列个数为4个。
2:使用cat /proc/cpuinfo,可以查看支持的cpu个数(processor+1)
#可以自己查看细节 ubuntu@ubuntu:~$ cat /proc/cpuinfo |grep processor processor : 0 processor : 1 processor : 2 processor : 3
3:修改ubuntu启动参数,支持大内存页,隔离cpu
isolcpus 配置的是隔离cpu,指定使用的cpu ==》可能有误,待理解,可以测试一下
在/etc/default/grub文件中修改GRUB_CMDLINE_LINUX对应值,
修改后执行 sudo update-grub
重启环境进行测试,如果启动不成功,可能是内存不够,内存设大一点。
#物理机: default_hugepages=1G hugepagesz=1G hugepages=20 isolcpus=0-7 #虚拟机: default_hugepages=1G hugepagesz=2M hugepages=1024 isolcpus=0-2 #具体大小视情况而定。重启虚拟机,使得hugepage和isocpus配置生效。
测试多队列网卡(虚拟机上的一个网卡)
1:概述
这里的测试:用wrk和nginx配合进行测试。
0:在多队列网卡的基础上,设置大内存页以及隔离cpu
1:配置nginx中进程数,以及配置cpu亲和性
2:查看多队列网卡,获取不同队列对应的中断号。
3:配置不同的中断号,与cpu核的绑定,特定的中断对应特定的核,方便测试。
2:安装nginx环境
在前面测试的基础上,有多队列网卡,设置了大内存页和隔离cpu的基础上,
进行nginx的安装以及测试:
tar -zxvf nginx-1.13.7.tar.gz tar -zxvf openssl-1.1.0g.tar.gz tar -zxvf pcre-8.41.tar.gz tar -zxvf zlib-1.2.11.tar.gz ./configure --prefix=/usr/local/nginx --with-http_realip_module --with-http_addition_module --with-http_gzip_static_module --with-http_secure_link_module --with-http_stub_status_module --with-stream --with-pcre=/home/ubuntu/install_code/nginx/pcre-8.41 --with-zlib=/home/ubuntu/install_code/nginx/zlib-1.2.11 --with-openssl=/home/ubuntu/install_code/nginx/openssl-1.1.0g make sudo make install ==》查看在/usr/local目录下产生nginx目录: cd /usr/local/nginx sudo ./sbin/nginx -c ./conf/nginx.conf #然后在网页上输入本机ip查看效果。 #用ps afx|grep nginx查看效果 #pcre ==>做正则表达式的 #zlib ==》做编码的
3:修改nginx配置环境,设置cpu亲和性
参考:https://www.cnblogs.com/pangbing/p/6537188.html
#在nginx配置文件中修改/增加如下 支持4个进程对应4个cpu,其他的8个cpu,2个cpu,绑定多个cpu可以自己研究 worker_processes 4; worker_cpu_affinity 0001 0010 0100 1000;
4:绑定中断和cpu
1:在/proc/interrupts 文件中查看对应的多队列网卡的中断号,可以看到这里是56-59
ubuntu@ubuntu:/usr/local/nginx$ cat /proc/interrupts |grep eth0 56: 14 0 0 14 PCI-MSI 1572864-edge eth0-rxtx-0 57: 3 0 0 0 PCI-MSI 1572865-edge eth0-rxtx-1 58: 4 0 0 0 PCI-MSI 1572866-edge eth0-rxtx-2 59: 2 0 0 0 PCI-MSI 1572867-edge eth0-rxtx-3 60: 0 0 0 0 PCI-MSI 1572868-edge eth0-event-4
2:手动对中断号进行cpu的绑定,
注意:需要su权限,
用xshell连接执行修改命令时会报错(bash: echo: write error: Invalid argument),试试直接在虚拟机环境上执行成功。
root@ubuntu:/proc/irq# cat /proc/irq/56/smp_affinity 00000000,00000000,00000000,00000008 root@ubuntu:/proc/irq# cat /proc/irq/57/smp_affinity 00000000,00000000,00000000,00000008 root@ubuntu:/proc/irq# cat /proc/irq/58/smp_affinity 00000000,00000000,00000000,00000008 root@ubuntu:/proc/irq# cat /proc/irq/59/smp_affinity 00000000,00000000,00000000,00000008 #如果xshell连接执行不成功,用vmware试试是成功的 root@ubuntu:/home# echo 00000001> /proc/irq/56/smp_affinity root@ubuntu:/home# echo 00000002> /proc/irq/57/smp_affinity root@ubuntu:/home# echo 00000004> /proc/irq/58/smp_affinity root@ubuntu:/home# echo 00000008> /proc/irq/59/smp_affinity #查看修改后的 root@ubuntu:/home# cat /proc/irq/56/smp_affinity 00000000,00000000,00000000,00000001 root@ubuntu:/home# cat /proc/irq/57/smp_affinity 00000000,00000000,00000000,00000002 root@ubuntu:/home# cat /proc/irq/58/smp_affinity 00000000,00000000,00000000,00000004 root@ubuntu:/home# cat /proc/irq/59/smp_affinity 00000000,00000000,00000000,00000008 #可以通过查看/proc/irq/56/smp_affinity_list 最后生效的,其实是对应的smp_affinity_list 其实是绑定的cpu号,可以多个 ubuntu@ubuntu:~$ cat /proc/irq/56/smp_affinity_list 0 ubuntu@ubuntu:~$ cat /proc/irq/57/smp_affinity_list 1 ubuntu@ubuntu:~$ cat /proc/irq/58/smp_affinity_list 2 ubuntu@ubuntu:~$ cat /proc/irq/59/smp_affinity_list 3 #如果有多于4个的,是继续如下配置的 root@ubuntu:/home# echo 00000010> /proc/irq/60/smp_affinity root@ubuntu:/home# echo 00000020> /proc/irq/61/smp_affinity root@ubuntu:/home# echo 00000040> /proc/irq/62/smp_affinity root@ubuntu:/home# echo 00000080> /proc/irq/63/smp_affinity
5:使用wrk性能测试工具对多队列网卡进行测试
注意,这里测试的是多队列网卡,要注意网卡的ip。
安装wrk( http 性能测试工具):
git clone https://gitee.com/mirrors/wrk.git make #这里可以直接在库下用生成的可执行文件wrk直接测试 #测试命令: ./wrk -c400 -d60s -t100 http://192.168.50.58/
测试环境的信息,建立在上文基础上,其实可以一个网卡进行测试的:
root@ubuntu:/usr/local/nginx# ifconfig eth0 Link encap:Ethernet HWaddr 00:0c:29:b2:2f:ce inet addr:192.168.50.58 Bcast:192.168.50.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:feb2:2fce/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:1096442 errors:0 dropped:0 overruns:0 frame:0 TX packets:1123779 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:87994929 (87.9 MB) TX bytes:505500636 (505.5 MB) eth1 Link encap:Ethernet HWaddr 00:0c:29:b2:2f:c4 inet addr:192.168.50.56 Bcast:192.168.50.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:feb2:2fc4/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:19445 errors:0 dropped:0 overruns:0 frame:0 TX packets:52 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1522713 (1.5 MB) TX bytes:5112 (5.1 KB) eth2 Link encap:Ethernet HWaddr 00:0c:29:b2:2f:d8 inet addr:192.168.50.60 Bcast:192.168.50.255 Mask:255.255.255.0 inet6 addr: fe80::20c:29ff:feb2:2fd8/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:19441 errors:0 dropped:0 overruns:0 frame:0 TX packets:52 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1522455 (1.5 MB) TX bytes:5112 (5.1 KB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:160 errors:0 dropped:0 overruns:0 frame:0 TX packets:160 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:11840 (11.8 KB) TX bytes:11840 (11.8 KB)
6:查看测试结果:
查看多队列网卡中中断产生所在cpu上的情况:主要看eth0,(中断号56,57,58,59) ===》这里数据以及隔离cpu的那个数字细节没有分析
可以从现象看出,56号中断数据在最后测试时,数据在cpu0, 57在cpu1, 58在cpu2, 59在cpu3 (cpu3上中断次数过多,是因为测试前的数据)
root@ubuntu:/usr/local/nginx# cat /proc/interrupts |grep eth 17: 5726 0 0 4420 IO-APIC 17-fasteoi ehci_hcd:usb1, ioc0, eth2 19: 405 0 0 3824 IO-APIC 19-fasteoi eth1 56: 79311 0 0 223321 PCI-MSI 1572864-edge eth0-rxtx-0 57: 3 38030 0 81500 PCI-MSI 1572865-edge eth0-rxtx-1 58: 7 0 38853 81592 PCI-MSI 1572866-edge eth0-rxtx-2 59: 7 0 0 116604 PCI-MSI 1572867-edge eth0-rxtx-3 60: 0 0 0 0 PCI-MSI 1572868-edge eth0-event-4
注意:一次中断,保证一个包的完整接收,但是并不是限定了连接就一致在这个cpu上。
这里的测试成功,我是建立在网络适配器修改为桥接模式,第一次net模式,没观察到数据变化(暂时没做测试和分析原因)。
总结:
1:概述实现
1:vmware环境通过增加网络适配器,增加多个网卡,并配置使网卡生效。
2:修改网卡名称为传统上的eth格式
3:多队列网卡的认识及测试(配置支持多队列网卡,绑定cpu进行)
4:认识wrk 性能测试工具
2:阻塞问题
1:增加适配器后,ifconfig查看依然没有增加的网卡对应信息,
===》需要在对应的配置文件中进行设置(ubuntu20和低版本有差异)
2:虚拟机环境上的网卡名并不是eth,
===》其实这个应该使没影响的,但是也是可以修改配置的,在/etc/default/grub做配置,增加的两个字段影响网络命名,可以查阅
3:明明在/etc/default/grub配置文件中已经增加字段,但是重启等各种手段都没有生效。
===》一定要执行sudo update-grub命令后,重启环境才会生效
4:如果ifconfig中还是没有相关多个网卡的信息。
===》注意/etc/network/interfaces中配置是否正确。
5:xshell连接测试虚拟机,执行echo 00000001> /proc/irq/56/smp_affinity命令时总报错。
===》直接在测试虚拟机上执行没有问题。
6:第一次测试的时候,多队列网卡虚拟机的网络适配器用的net模式,没观察到具体数据(待测试)
7:隔离cpu对cpu使用的影响(待测试)
参考:修改网卡eth:https://www.cnblogs.com/itwangqiang/p/14302252.html
dpdk环境搭建:https://zhuanlan.zhihu.com/p/336938230
nginx配置worker_cpu_affinity:https://blog.csdn.net/u011957758/article/details/50959823
Biosdevname & net.ifnames 命名规则: http://benjr.tw/93340
-
多队列网卡简介
2017-10-03 20:26:19多队列网卡简介转自:http://blog.csdn.net/turkeyzhou/article/details/7528182/
多队列网卡是一种技术,最初是用来解决网络IO QoS (quality of service)问题的,后来随着网络IO的带宽的不断提升,单核CPU不能完全处满足网卡的需求,通过多队列网卡驱动的支持,将各个队列通过中断绑定到不同的核上,以满足网卡的需求。
常见的有Intel的82575、82576,Boardcom的57711等,下面以公司的服务器使用较多的Intel 82575网卡为例,分析一下多队列网卡的硬件的实现以及linux内核软件的支持。
1.多队列网卡硬件实现
图1.1是Intel 82575硬件逻辑图,有四个硬件队列。当收到报文时,通过hash包头的SIP、Sport、DIP、Dport四元组,将一条流总是收到相同的队列。同时触发与该队列绑定的中断。
图1.1 82575硬件逻辑图
2. 2.6.21以前网卡驱动实现
kernel从2.6.21之前不支持多队列特性,一个网卡只能申请一个中断号,因此同一个时刻只有一个核在处理网卡收到的包。如图2.1,协议栈通过NAPI轮询收取各个硬件queue中的报文到图2.2的net_device数据结构中,通过QDisc队列将报文发送到网卡。
图2.1 2.6.21之前内核协议栈
图2.2 2.6.21之前net_device
3. 2.6.21后网卡驱动实现
2.6.21开始支持多队列特性,当网卡驱动加载时,通过获取的网卡型号,得到网卡的硬件queue的数量,并结合CPU核的数量,最终通过Sum=Min(网卡queue,CPU core)得出所要激活的网卡queue数量(Sum),并申请Sum个中断号,分配给激活的各个queue。
如图3.1,当某个queue收到报文时,触发相应的中断,收到中断的核,将该任务加入到协议栈负责收包的该核的NET_RX_SOFTIRQ队列中(NET_RX_SOFTIRQ在每个核上都有一个实例),在NET_RX_SOFTIRQ中,调用NAPI的收包接口,将报文收到CPU中如图3.2的有多个netdev_queue的net_device数据结构中。
这样,CPU的各个核可以并发的收包,就不会应为一个核不能满足需求,导致网络IO性能下降。
图3.1 2.6.21之后内核协议栈
图3.2 2.6.21之后net_device
4.中断绑定
当CPU可以平行收包时,就会出现不同的核收取了同一个queue的报文,这就会产生报文乱序的问题,解决方法是将一个queue的中断绑定到唯一的一个核上去,从而避免了乱序问题。同时如果网络流量大的时候,可以将软中断均匀的分散到各个核上,避免CPU成为瓶颈。
图4.1 /proc/interrupts
5.中断亲合纠正
一些多队列网卡驱动实现的不是太好,在初始化后会出现图4.1中同一个队列的tx、rx中断绑定到不同核上的问题,这样数据在core0与core1之间流动,导致核间数据交互加大,cache命中率降低,降低了效率。
图5.1 不合理中断绑定
linux network子系统的负责人David Miller提供了一个脚本,首先检索/proc/interrupts文件中的信息,按照图4.1中eth0-rx-0($VEC)中的VEC得出中断MASK,并将MASK
写入中断号53对应的smp_affinity中。由于eth-rx-0与eth-tx-0的VEC相同,实现同一个queue的tx与rx中断绑定到一个核上,如图4.3所示。
图4.2 set_irq_affinity
图4.3 合理的中断绑定
set_irq_affinity脚本位于http://mirror.oa.com/tlinux/tools/set_irq_affinity.sh。
6.多队列网卡识别
#lspci -vvv
Ethernet controller的条目内容,如果有MSI-X && Enable+ && TabSize > 1,则该网卡是多队列网卡,如图4.4所示。
图4.4 lspci内容
Message Signaled Interrupts(MSI)是PCI规范的一个实现,可以突破CPU 256条interrupt的限制,使每个设备具有多个中断线变成可能,多队列网卡驱动给每个queue申请了MSI。MSI-X是MSI数组,Enable+指使能,TabSize是数组大小。
-
顶
- 3
-
踩
-
多队列网卡及网卡中断绑定阐述
2017-12-24 15:21:41多队列网卡顾名思义就是由原来的单网卡单队列变成了现在的单网卡多队列。多队列网卡是一种技术,最初是用来解决网络IO QoS (quality of service)问题的,后来随着网络IO的带宽的不断提升,单核CPU不能完全处满足... -
多队列网卡CPU中断均衡
2019-08-07 17:05:30https://blog.csdn.net/hankerzero/article/details/55093897 http://www.simlinux.com/2017/02/28/net-softirq.html https://blog.csdn.net/vevenlcf/article/details/78885229 -
Linux多队列网卡的硬件的实现详解
2021-05-11 17:06:156.多队列网卡识别#lspci -vvvEthernet controller的条目内容,如果有MSI-X && Enable+ && TabSize > 1,则该网卡是多队列网卡,如图4.4所示。图4.4 lspci内容Message Signaled Interrupts(MSI)是... -
多队列网卡介绍以及Suricata应用场景
2018-08-29 14:23:43对称多处理器系统,是指在一个计算机上汇集了一组CPU,各CPU之间共享内存子系统以及总线结构(或者说是两个或多个同样的处理器通过一块共享内存彼此连接。) 作用:适用于多处理器计算机 APIC(A... -
高并发多队列网卡设置CPU亲和性项目记录
2018-04-17 12:01:30做ssl加速卡(高并发)测试又遇到相同的问题,多队列网卡软中断过高,记录备忘 场景:nginx模拟业务服务器,worker不绑定;网卡队列亲和性不设置 结果:那叫一塌糊涂,3w TPS 0号CPU就满了, 其中si多... -
多队列网卡介绍
2019-01-11 17:31:00多队列网卡是指一个网卡上有多个队列,内核会给每个队列注册一个中断号,具体可以在/proc/interrupts | grep {网卡} 查看,其中第一列是中断号,最后一列是网卡队列信息。CPU和中断号有亲和性,一般网卡中断和一个... -
网卡多队列原理及学习
2021-01-26 18:57:32对称多处理器系统,是指在一个计算机上汇集了一组CPU,各CPU之间共享内存子系统以及总线结构(或者说是两个或多个同样的处理器通过一块共享内存彼此连接。) 作用:适用于多处理器计算机 APIC(Advanced ... -
网卡多队列及中断绑定
2021-05-12 12:21:01多队列网卡是一种技术,最初是用来解决网络IO QoS (quality of service)问题的,后来随着网络IO的带宽的不断提升,单核CPU不能完全处满足网卡的需求,通过多队列网卡驱动的支持,将各个队列通过中断绑定到不同的核上... -
DPDK-虚拟机配置网卡多队列
2021-09-07 11:19:20配置网卡多队列 1.设置巨页 sudo vim /etc/default/grub 如果是虚拟机: GRUB_CMDLINE_LINUX改成 GRUB_CMDLINE_LINUX="find_preseed=/preseed.cfg noprompt ... -
多队列网卡简介以及Linux通过网卡发送数据包源码解读
2021-05-12 06:19:41首先我们看一下一个主流多队列网卡(E1000)跟多核CPU之间的关系图: 非多队列:linux的网卡由结构体net_device表示,一个该结构体对应一个可以调度的数据包发送队列。数据包的实体在内核中以结构体sk_buff(skb),形如... -
linux网卡多队列技术
2021-07-17 19:12:002 中断、队列、CPU之间关系 2.1 配置网卡多队列 (1)判断当前系统环境是否支持多队列网卡,执行命令: lspci -vvv 如果在Ethernet项中。含有MSI-X: Enable+ Count=9 Masked-语句,则说明当前系统环境是支持多队列... -
常见Intel网卡芯片对比,多队列网卡介绍
2022-04-06 11:05:05常见Intel网络芯片对比 Intel 82580,intel I350 也是8个RSS Queue.... ...MSI-X:533MHz PPc处理器 LSI SAS 9211-8i评测 ...VMDq:Io虚拟化:虚拟设备队列VMDq技术解析VMDc:Io虚拟化:虚拟直接连接VMDc技术解析.. -
网卡多队列及中断均衡
2021-05-12 12:19:35背景记录网卡多队列及中断均衡相关的笔记,供参考。概念网卡多队列需要硬件和驱动同时支持,通常新服务器上的网卡都是支持的。网卡多队列,即每个CPU一个网卡队列,每个队列对应一个独立的中断。中断均衡问题每个... -
Linux网卡多队列学习笔记
2022-04-06 14:41:01Linux网卡多队列的原理 Linux kernel在2.6.21之前不支持网卡多队列的特性,也就是一个网卡只能申请一个中断号。 在2.6.21开始支持网卡多队列,当网卡驱动加载的时候,通过获取网卡型号得到网卡支持的网卡队列数量。... -
CentOS 配置网卡多队列
2020-04-22 16:22:42网卡多队列指实例规格支持的最大网卡队列数。单台实例vCPU处理网络中断存在性能瓶颈时,您可以将实例中的网络中断分散给不同的CPU处理,从而提升性能。 前提条件 您的实例规格必须支持网卡多队列功能。支持多... -
网卡多队列设置
2020-09-15 13:53:36一、网卡多队列的出现 通常情况下,一张网卡会有一个队列用来接发收网络数据包,我们所说的一个队列你也可以理解成一个处理数据包的进程。 但是随着时代的发展,网卡支持的流量带宽越来越大,如果还是使用一个队列... -
多队列网卡特性
2015-01-23 10:44:52多队列网卡是一种技术,最初是用来解决网络IO QoS (quality of service)问题的,后来随着网络IO的带宽的不断提升,单核CPU不能完全处满足网卡的需求,通过多队列网卡驱动的支持,将各个队列通过中断绑定到不同的... -
多队列网卡
2015-09-02 18:25:25多队列网卡是一种技术,最初是用来解决网络IO QoS (quality of service)问题的,后来随着网络IO的带宽的不断提升,单核CPU不能完全处满足网卡的需求,通过多队列网卡驱动的支持,将各个队列通过中断绑定到不同的...