http://laoar.github.io/blog/2017/05/07/rps/

TL;DR

  • RPS 
    即receive side steering,利用网卡的多队列特性,将每个核分别跟网卡的一个首发队列绑定,以达到网卡硬中断和软中断均衡的负载在各个CPU上。 
    他要求网卡必须要支持多队列特性。

  • RPS 
    receive packet steering 
    他把收到的packet依据一定的hash规则给hash到不同的CPU上去,以达到各个CPU负载均衡的目的。 
    他只是把软中断做负载均衡,不去改变硬中断。因而对网卡没有任何要求。

  • RFS 
    receive flow steering 
    RFS需要依赖于RPS,他跟RPS不同的是不再简单的依据packet来做hash,而是根据flow的特性,即application在哪个核上来运行去做hash,从而使得有更好的数据局部性。

我们可以看到很多案例,使用这些特性后提醒了网络包的处理能力,从而提升QPS,降低RT。

但是,我们知道,任何一个优化特性都不是普遍适用的,都有他特定的场景来应用。 
很多人对此可能会有疑惑,那很多优化功能不是都已经作为默认配置了么,如果不是普遍适用的,干嘛还要作为默认配置呢? 
其实很简单,一个优化特性可以作为默认配置,依据我的理解,只需要满足下面这些特征即可:

  • 对某些场景可以显著提升性能
  • 对大部分场景无害
  • 对某一部分场景可能会损伤性能

所以Linux的很多配置都是可以灵活配置供选择的。

下面我们就来看下RPS这些特性在哪些场景下才能发挥作用。

问题描述

业务方在使用KVM虚拟机进行性能压测时,发现某一个核的softirq占比特别高,如下所示:

1
2
3
4
5
6
7
$ mpstall -L ALL 1
03:44:20 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
03:44:21 PM all 68.58 0.00 20.70 0.00 0.00 5.49 0.00 0.00 0.00 5.24
03:44:21 PM 0 70.00 0.00 23.00 0.00 0.00 0.00 0.00 0.00 0.00 7.00
03:44:21 PM 1 60.78 0.00 16.67 0.00 0.00 21.57 0.00 0.00 0.00 0.98
03:44:21 PM 2 71.29 0.00 21.78 0.00 0.00 0.00 0.00 0.00 0.00 6.93
03:44:21 PM 3 73.74 0.00 21.21 0.00 0.00 0.00 0.00 0.00 0.00 5.05

一句话解释:这个kvm虚拟机只有一个网卡,有网络包到达这个网卡后,它会给某一个cpu(如果没有设置亲和性,这个可以认为是随机的一个cpu,然后就会一直固定在这个cpu上)发中断,通知该cpu来处理这个包,然后cpu就会触发一个软中断把该包送到tcp/ip协议栈(对于tcp包而言)里去处理,该包被放入某一个socket的receive buffer中(如果是一个数据包),软中断结束。 
%soft就是指的CPU耗在软中断处理上的时间。 
可以看到核1的%soft很高,其他的核的%soft基本为0. 
所以就想着把核1的%soft给均摊下,是否可以提升QPS。 
我们想到的方法是网卡多队列,或者RPS/RFS。用这种手段来把网卡软中断给均摊到其他的核上去。

其实,看到前面mpstat的显示,如果对网卡多队列,RPS/RFS很熟悉,就会意识到他们在这里不适用。 
可惜理解的不深,交了这次学费。

使能网卡多队列后,果然是QPS不但没有提升,反而有下降。 
下面就是这次调优交的学费。

为了使描述更清晰(其实是因为我做分析的这个kvm虚拟机上没有网卡多队列,但是不影响,导致性能下降的原因是一致的),我们只分析RPS来看下为什么性能会下降。

RPS的原理概述

  • 基于CentOS-7

在这之前,软中断只能在硬中断所在CPU上处理,使用RPS后,网卡软中断就可以分发到其他的CPU上去做处理了。

使能RPS后为什么会导致QPS下降?

如上图所示,使能了RPS后,会增加一些额外的CPU开销:

  1. 收到网卡中断的CPU会向其他CPU发IPI中断,这体现在CPU的%irq上
  2. 需要处理packet的cpu会收到NET_RX_SOFTIRQ软中断,这体现再CPU的%soft上。请注意,RPS并不会减少第一个CPU的软中断次数,但是会额外给其他的CPU增加软中断。他减少的是第一个CPU的软中断的执行时间,即,软中断里不再需要那么多的时间去走协议栈做包解析,把这个时间给均摊到其他的CPU上去了。

量化对比数据

硬中断次数的变化

这可以通过/proc/interrupts来观察

1
$ watch -d -n 1 'cat /proc/interrupts'
  • 使能RPS之后: 

  • 使能RPS之前: 

可以看到,是能RPS后,增加了很多的Function call interrups,即IPI。 
而virtio0-input.0(虚拟网卡产生的中断,类似于图中NIC产生的中断)仍然只发给CPU1. 
也可以通过dstat来看整体次数的对比

  • 使能RPS之后:
1
2
3
4
5
6
7
$ dstat
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
62 23 4 0 0 12| 0 0 |7096k 11M| 0 0 | 49k 2261
74 13 4 0 0 9| 0 0 |4003k 6543k| 0 0 | 31k 2004
59 22 5 0 0 13| 0 4096B|6710k 10M| 0 0 | 48k 2220
  • 使能RPS之前:
1
2
3
4
5
6
7
8
$ dstat
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
64 23 6 0 0 7| 0 8192B|7917k 12M| 0 0 | 27k 1922
64 22 6 0 0 8| 0 0 |7739k 12M| 0 0 | 26k 2210
61 23 9 0 0 7| 0 0 |7397k 11M| 0 0 | 25k 2267
94 4 0 0 0 1| 0 0 |1262k

软中断次数的变化

这可以通过/proc/softirq来观察

1
$ watch -d -n 1 'cat /proc/softirq'
  • 使能RPS之前: 

  • 使能RPS之后: 

可以看到,CPU1上的RX_NET数相差不大比较接近,但是CPU0/2/3上各自都增加了NET_RX.

各个CPU利用率的变化

这可以通过mpstat来观察

1
$ mpstat -P ALL 1
  • 使能RPS之后
1
2
3
4
5
6
Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
Average: all 66.21 0.00 17.73 0.00 0.00 11.15 0.00 0.00 0.00 4.91
Average: 0 68.17 0.00 18.33 0.00 0.00 7.67 0.00 0.00 0.00 5.83
Average: 1 60.57 0.00 15.81 0.00 0.00 20.80 0.00 0.00 0.00 2.83
Average: 2 69.95 0.00 19.20 0.00 0.00 7.01 0.00 0.00 0.00 3.84
Average: 3 66.39 0.00 17.64 0.00 0.00 8.99 0.00 0.00 0.00 6.99
  • 使能RPS之前
1
2
3
4
5
6
Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
Average: all 70.18 0.00 19.28 0.00 0.00 5.86 0.00 0.00 0.00 4.68
Average: 0 73.25 0.00 21.50 0.00 0.00 0.00 0.00 0.00 0.00 5.25
Average: 1 58.85 0.00 14.46 0.00 0.00 23.44 0.00 0.00 0.00 3.24
Average: 2 74.50 0.00 20.00 0.00 0.00 0.00 0.00 0.00 0.00 5.50
Average: 3 74.25 0.00 21.00 0.00 0.00 0.00 0.00 0.00 0.00 4.75

可以看到,整体而言,CPU的%soft增大了很多,%usr下降了一些。 
我们知道%usr是衡量用户态程序性能的一个指标,%usr越高,意味着执行业务代码的时间就越多。如果%usr下降,那就意味着执行业务代码的时间变少了,这显然对于业务性能是一个危险信号。 
至于%usr里面如何来提高业务代码执行效率,是另外的问题了,不讨论。

结论,RPS适用的场景

使能了RPS后,会增加CPU的%soft,如果业务场景本身就是CPU密集的,CPU的负载已经很高了,那么RPS就会挤压%usr,即挤压业务代码的执行时间,从而导致业务性能下降。

适用场景

RPS如果想要提升业务性能,前提是除了网卡中断所在的CPU外,其他的CPU都需要有一定的空闲时间,这样使能RPS才能带来收益,否则就会带来额外开销导致性能下降。
在这个场景下,RPS搭配RFS会带来更好的收益,不讨论。

有没有更优的解决方案?

答案肯定是有的。

It is a SECRET!

为什么使能RPS/RFS, 或者RSS/网卡多队列后,QPS反而下降?的更多相关文章

  1. Linux RSS/RPS/RFS/XPS对比

    RSS适合于多队列网卡,把不同的流分散的不同的网卡多列中,至于网卡队列由哪个cpu处理还需要绑定网卡队列中断与cpu RPS:适合于单队列网卡或者虚拟网卡,把该网卡上的数据流让多个cpu处理 RFS: ...

  2. 网卡优化RPS/RFS

    网卡优化 RSS receive side scaling,网卡多队列,需要硬件支持.网卡接收到网络数据包后,要发送一个硬件中断,通知CPU取数据包.默认配置,都是由CPU0去做. RPS recei ...

  3. linux kernel 关于RSS/RPS/RFS/XPS的介绍

    Introduction============ This document describes a set of complementary techniques in the Linuxnetwo ...

  4. RPS/RFS/ GRO

    http://www.cnhalo.net/2016/09/13/linux-gro/ GRO(Generic receive offload): 在napi poll里把小包封装成大包再递交给协议栈 ...

  5. Linux RPS/RFS 实现原理浅析

    本文快速解析一下RPS/RFS的基本原理. RPS-Receive Packet Steering 下面这个就是RPS的原理:  其实就是一个软件对CPU负载重分发的机制.其使能的作用点在CPU开始处 ...

  6. 【转帖】网卡多队列技术与RSS功能介绍

    网卡多队列技术与RSS功能介绍 2017年02月08日 15:44:37 Murphy_0806 阅读数 10665 标签: rss网卡dpdk 更多 个人分类: DPDK https://blog. ...

  7. 修改网卡MAC地址后出现问题:device eth0 does not seem to be present, delaying initialization

    修改网卡MAC地址后出现问题:device eth0 does not seem to be present, delaying initialization   1.修改网卡对应的文件,将配置文件中 ...

  8. dpdk-18.11网卡多队列RSS设置

    背景 最近在做将基于dpdk-16.11.1开发的程序,转移到基于dpdk-18.11版本下开发.遇到了网卡RSS配置的问题,在这里纪录一下. 问题 dpdk-16.11.1 在dpdk-16.11. ...

  9. 解决Ubuntu Server 12.04换了网卡MAC地址后 网络不可用的问题.

    重装了系统,新建了一个ubuntu虚拟机,加载原来的镜像,结果启动后网络变得不正常了,提示信息 Waiting for network configuration...Waiting up to 60 ...

随机推荐

  1. js将网址转为二维码并下载图片

    将一个网址转为二维码, 下面可以添加文字, 还提供下载功能 利用的是 GitHub上面的qrcode.js 和canvas <!DOCTYPE html> <html> < ...

  2. MySQL 数据类型对比:char 与 varchar;varchar 与 text;datetime 与 timestamp;blob 与 text;

    char 与 varchar char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉.所以 char 类型存储的字符串末尾不能有空格,varchar 不限于此. char(n) 固 ...

  3. 十二、springboot(七)打包启动

    1.打包 mvn clean package -Dmaven.test.skip=true2.运行 a.不能后台运行 java -jar 项目.jar     b.可后台运行        java ...

  4. 二维指针的malloc内存分配(转)

    写代码的时候会碰到多维数组的内存分配和释放问题,在分配和释放过程中很容易出现错误.下面贴上一些示例代码,以供参考. 如果要给二维数组(m*n)分配空间,代码可以写成下面: char **a, i; 1 ...

  5. secureCRT关闭连接自动关闭tomcat服务

    下午遇到一个神奇的问题: secureCRT登陆某个服务器,用shell脚本启动./catalina.sh start,打开日志tail -f catalina.out,此时 手动关闭连接窗口,导致t ...

  6. Maven3.5.0安装与配置+Eclipse应用

    Maven是一个优秀的构建工具(类似于 Ant, 但比 Ant 更加方便使用),能帮助我们自动化构建过程,从清理.编译.测试到生成报告,再到打包和部署.只需要输入简单的命令,Maven就可以帮我们处理 ...

  7. CentOS6.5 安装+ Tengine + PHP + MySQL

    简介: Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性.Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了 ...

  8. JAVAFX开发桌面应用

    javafx中文版文档: http://www.yiibai.com/javafx/ JavaFX之FXController详解 JavaFx系列教程 含打包部署 javafx之两种局部界面的呈现方式 ...

  9. 信号滤波模块verilog代码---UNLOCK,LOCK状态机方式

    信号滤波模块verilog代码 `timescale 1ns / 1ps /////////////////////////////////////////////////////////////// ...

  10. WPF实现打印用户界面功能

    方式一:public bool Print(string pathStr) { try { if (File.Exists(pathStr) == false) return false; var p ...