百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

网络参数 RSS、RPS、RFS、aRFS 学习总结

cac55 2024-12-24 11:04 51 浏览 0 评论

最近学习,发现网络参数(包括内核参数、网卡参数)非常多,搞得人云里雾里,非常头大。因此打算在这里对学习到的东西做个总结,方便知识的梳理和以后的复习。

Receive Side Scaling (RSS)

RSS 是一个 Linux 网络协议栈中的调度机制。它的主要作用是将数据包路由到不同的接收队列,进而由该队列所对应的 CPU 进行处理,从而实现对数据包处理的负载均衡。

在硬件上,通常使用 hash 函数(一般是 Toeplitz hash)和长度为 128 (2^7) 的置换表来实现。具体做法是,首先将网络和传输层头部的一些信息(如地址端口四元组)通过 hash 函数计算出一个 hash 值,然后取该 hash 值的后 7 位。将这 7 位数作为索引,在置换表中寻找相应的值,该值即为相应的队列。

1
2
[hash value] : [queue number]
...

网卡的置换表可以通过命令 ethtool --show-rxfh-indir <eth0> 来获取,例子如下:

可见一共有 128 条表项,完全均匀分配给了队列 rx-0 → rx-3。该表可通过命令 ethtool —set-rxfh-indir 进行配置。

上述机制实现了从数据包到队列的对应,为了真正实现负载均衡,我们还需要协调好从队列到 CPU 的对应关系。又因为每个队列对应一个中断(参考上一篇),所以我们可以通过中断号绑定的方式来实现队列和 CPU 的对应。关于此,请参考关于此,请参考 理解 CPU、中断、队列、进程的绑定关系 - 麋鹿博客 (Elk blog) | 一个分享知识和乐趣的地方 。

RSS

本文RSS、RPS、RFS、aRFS图片来源:Linux Network Scaling: Receiving Packets (garycplin.blogspot.com)

技巧

该文档 给出建议,想要实现低延时,应该配置 CPU 数量的队列(即每个 CPU 一个)。对此,笔者的理解是,如果队列数量少了,则可能会有 CPU 闲着,处理不够及时。队列数量多了也没用,因为 CPU 就那么多。

针对以高速率为目的的网络,文档建议使用尽可能少的队列,在这种配置下,不会出现接收队列因为一个 CPU 饱和而溢出的情况。因为在启用中断合并(如 NAPI)的情况下,队列越多,中断数越多。

Receive Packet Steering (RPS)

RPS 逻辑上是 RSS 的软件实现,但又不完全一样。RSS 可以为每个数据包选择接收队列,因此也就选择了相对应的执行中断处理的 CPU;而在 RPS 中,中断由默认队列触发,中断处理函数结束之后,选择进行后续协议处理的 CPU。

RPS

引用

RPS 不会增加额外的硬件设备中断,但是引入了处理器间中断(IPI)。

— Scaling in the Linux Networking Stack — The Linux Kernel documentation

RPS 使用和 RSS 相同的 hash 计算方式,并且每个队列对应一个 CPU 列表。使用计算得到的 hash 值模上 CPU 列表的长度就得到了 CPU 号。当确定了新的 CPU 之后,数据包会被放置到相应 CPU 的 backlog 队列中。随后在新的 CPU 上触发一个 IPI 中断,告诉该 CPU 有 RPS 过来的新包需要其处理。

1
[CPU id] = [hash value] mod [len(CPU list)]

在编译内核时通过设置 CONFIG_RPS 参数来设置是否支持 RPS 功能,系统默认为开。但是需要为想要使用 RPS 功能的队列配置上面提到的 CPU 列表。

RPS 配置文件为 /sys/class/net/<device>/queue/<rx-queue>/rps_cpus ,其中 <device> 表示网络设备,如 eth0<rx-queue> 表示接收队列,如 rx-0

该文件中存储的是一个十六进制的 bitmap。每一个二进制比特代表一个 CPU,最右边对应序号最小的 CPU(即 CPU0),最左边代表最大的。(参考上一篇)

每个队列的配置默认为 0,即关闭 RPS 功能。如果要打开,用户可以根据规则自行设置。

技巧

如果网卡只支持单个队列,并且有多个 CPU 的的话,在 NUMA 系统中,一般将 RPS CPU 设置为在相同 domain 的 CPU,非 NUMA 系统就无所谓了,因为设置为每一个 CPU 的性能都是一样的。

对于多队列网卡,一般系统不会同时启用 RSS 和 RPS,因为这没什么好处。但也有例外,比如网卡所支持的队列数目少于 CPU 数,也就是每个 CPU 还分不到一个接收队列,那么使用 RPS 可能会使得 CPU 的任务分布更高效。

Receive Flow Steering (RFS)

以上机制很好地保证了数据包处理的负载均衡,可以将处理任务合理的分配到所有的 CPU 上。

但是,有时候我们还需要考虑其他的因素。比如,网卡收到了属于一个运行在 CPU0 上的进程的数据包,那么这些数据包被 CPU0 处理会比其他 CPU 处理更高效。

原因很简单直观,数据在 CPU 内传递比跨 CPU 传递要更节省时间。因此,我们希望数据包尽量能够被其所属的进程所在的 CPU 处理,至少能够被同属一个 NUMA 域的 CPU 处理。

RFS 机制就是为了实现这一点。该机制利用了与 RSS/RPS 类似的 hash 和查找策略,即使用 hash 函数根据包头信息计算得到一个 hash 值,然后作为索引查表。但与之不同的是,RFS 所查找的匹配表(rps_sock_flow_table)中存储的是数据包所属进程所在的 CPU

1
2
[hash value] : [CPU id]
...

回顾一下,RPS/RSS 中存储的是预先配置好的 CPU 列表。

如果能查找到有效的 CPU,就按照与 RPS 相同的机制,将数据包入队到 CPU 对应的 backlog 队列中;如果查找不到,那么就直接按照 RPS 机制转发。

与 RPS 预先配置好的 CPU 列表不同,rps_sock_flow 表是动态更新的。如果有数据包的收发操作,如 inet_recvmsg(), inet_sendmsg(), inet_sendpage(), tcp_splice_read() 等操作,则会插入新的值。类似的情况还发生在进程被调度到新的 CPU 的时候。这时候就需要更新匹配表中的值。如果原来的 CPU 队列上还有未处理完的数据包,那么就会发生乱序。

为了避免乱序,RFS 使用了另一个表 —— rps_dev_flow 表,每个网卡队列对应一个该表。该表的索引依旧是包头的 hash 值,每个索引对应两个字段:1) 现在的 CPU(也就是该数据包所属流已经把数据包放在其队列上等待其内核处理的 CPU)号。2) 当该流最后一个数据包到达后,该 CPU 的 backlog 队列的尾计数器值。

RFS

当选择处理数据包的 CPU 时,首先检查 rps_sock_flow 表和 rps_dev_flow 表中对应的 CPU 值是否相同。如果一样,说明进程还是运行在相同的 CPU 上,仍将数据包放在该 CPU 的队列上,没有问题。如果不一样,那么就看以下三个情况:

  1. 现在的 CPU 队列头计数器 ≥ rps_dev_flow 表中的队列尾计数器。
  2. 现在的 CPU 未被设置 (≥ nr_cpu_ids)。
  3. 现在的 CPU 下线了。

如果上面任意一条满足,就将现在的 CPU 更新为 Desired CPU (即 rps_sock_flow 表中的值)。否则,仍在原(现) CPU 上执行。

直观的理解上面的判断机制,那就是:当进程切换 CPU 时,先判断原 CPU 队列上有没有未处理完的包,如果有就不切换;如果没有,就切换。

Linux 内核编译可通过允许 CONFIG_RPS 来使能该功能,一般默认允许。但要是想让 RFS 真正工作,还需要进行配置上面提到的两个表,他们的配置路径分别为:

1
2
/proc/sys/net/core/rps_sock_flow_entries
/sys/class/net/<dev>/queues/rx-<n>/rps_flow_cnt

技巧

该文档 建议 rps_sock_flow_entries 的数量应该跟活跃流的数量相当,然后四舍五入取二的指数值。进一步,文档建议对于一般负载的服务器,值取为 32768 (2^15) 效果比较好。对于 rps_flow_cnt 的取值应该参考 rps_sock_flow_entries,因为前者是每个队列一个,后者是全局的,所以只要将 rps_flow_cnt 取为 rps_sock_flow_entries / N 就行,其中 N 为队列数。

关于该建议,本人的理解是:最好能够给每一个活跃的流都能分配一个表项,使其能够准确找到对应的 CPU。

Accelerated RFS

Accelerated RFS 之于 RFS 相当于 RSS 之于 RPS。Accelerated RFS 在硬件上就可以选择正确的队列,随后触发该数据包所属流所在的 CPU 的中断。由此可见,如果想要在硬件上实现队列选择,我们需要一个从流到硬件队列的对应关系。

从上文可知,我们已经有了一个从流到 CPU 的映射关系,记录在 rps_dev_flow 表中。然后,我们也有 CPU 和硬件队列的关系,通过 /proc/irq/<irq_num>/smp_affinity 进行配置。

信息

回顾一下 rps_dev_flow 表中存储的信息,如果该表被更新,说明有某个进程被创建,或者进程连同协议处理完全迁移到了一个新的 CPU。

aRFS

每当 rps_dev_flow 表中的条目被更新,网络协议栈就会调用驱动中的 ndo_rx_flow_steer 函数来更新流到硬件队列的对应关系。

Accelerated RFS 需要在编译阶段使能 CONFIG_RFS_ACCEL,并且需要硬件和驱动的支持。此外,还需要使用 ethtool 设置 ntuple 过滤。其他的就不需要配置了。

技巧

Accelerated RFS 机制可以将数据包直接放在最终的 CPU 硬件队列上,所以性能应该是要比 RFS 高。因此,当硬件支持该选项,应该选择此机制。

总结

回顾一下这些机制之间的关系。首先是 RSS/RPS,该机制在接收数据包的时候,通过手动配置,甚至是根据负载情况的自动配置(如 irqbalance),来把数据包的处理负载均匀分配到不同的 CPU 上。RSS/RPS 仅根据负载大小进行判断,但是这可能导致从协议栈处理到上层应用处理之间数据包的转移。

因此 RFS/aRFS 更进一步,在进行 CPU 选择的时候考虑上层应用所处位置,对每一个流都配置一个 Desired CPU。因此,在为数据包选择 CPU 的时候,会优先选择 Desired CPU。

参考

  1. Scaling in the Linux Networking Stack — The Linux Kernel documentation
  2. Toeplitz Hash Algorithm - Wikipedia
  3. 8.7. Receive Packet Steering (RPS) Red Hat Enterprise Linux 6 | Red Hat Customer Portal
  4. SMP IRQ affinity — The Linux Kernel documentation
  5. Linux Network Scaling: Receiving Packets (garycplin.blogspot.com)


转自:https://blog.luckyoung.org/posts/page/2/

相关推荐

小车五位自动循环往返控制_小车自动往返控制系统

需求描述:用三相异步电动机拖动一辆小车在A、B、C、D、E五点之间自动循环往返运行,小车初始在A点,按下启动按钮,小车依次前进到B、C、D、E点,并分别停止2s返回到A点停止。按下停止...

自动灌溉系统_自动灌溉系统by

需求描述:PLC时钟设定每日6:00、18:00自动启动灌溉系统,每次运行15分钟后停止;非定时时段按下手动灌溉按钮,立即启动并运行15分钟;土壤湿度传感器检测到湿润时,跳过本次定时灌溉...

主板ERP开启还是关闭好_主板设置erp是什么

主板功能的开启与关闭,本质是在“节能环保”和“使用便利”之间做选择。为帮你快速决策,先给出直接结论,再深入解析原理、影响及操作步骤,让你根据自身需求精准设置。一、直接结论:ERP功能如何选?...

新电脑必做5项设置!做完再玩,流畅安全多用三年

刚拿到新电脑,兴奋之余先别急着开机畅玩!做好以下这5大设置,能让你的爱机长期保持流畅如新,安全又省心。尤其是最后一招,很多老用户都不知道!1关闭隐私常规,杜绝数据偷跑新电脑首次开机进行系统初始化时,...

属于 PHP 开发者的 Supervisor 实用指南

属于PHP开发者的Supervisor实用指南在PHP开发中,我们经常需要运行一些后台进程:队列处理、长时间运行的脚本、WebSocket服务器等。这些进程可能会因为各种原因意外退出,手...

领导半夜12点微信派活?三句高情商回复,反手拿捏让他不敢再烦

友友们大家来啦!今天来和大家一起分享精彩话题老规矩先点赞再看文!0102别在这里害人了,现在能保住工作就烧高香了,再得瑟,明天早上去办离职0304很简单,把他一起拉上,每半小时打电话或语音汇报,一两次...

&quot;零点黑科技!硬盘自动备份+离线神操作,服务器数据安全躺赢&quot;

公司有一台服务器,数据库需要每天零点进行数据库备份,要求在本机备份一次,再在移动硬盘上异地备份一次。备份完成后硬盘自动离线。具体思路如下:数据库自动备份时间为每天0点,备份过程约需1分钟。0点时开启硬...

峰谷电:白天贵、晚上便宜,你家真的适合开通吗?

电费单又超预算了?别急着关掉空调,其实你可能错过了一个"电费打折"的机会——峰谷电。它就像电影院的日场和夜场票,白天贵、晚上便宜,聪明利用,电费真的能省下来。一、峰谷电是什么?峰谷电把...

电脑开机密码设置全指南:从基础到进阶的安全防护

在数字化时代,电脑存储着大量个人隐私和重要数据,设置开机密码是保护信息安全的第一道防线。本文将系统介绍Windows、macOS、Linux三大主流操作系统及BIOS层面的密码设置方法,同时涵盖密码管...

自动喷香机_香薰机自动喷香机

需求描述:PLC时钟设定每日9:00、14:00、18:00自动启动喷雾,每次喷雾3秒后停止;非定时时段按下手动喷雾按钮,立即喷雾3秒;香薰液缺液传感器检测到液位过低时,停止喷雾并亮报警...

macbook系统自动启动项在哪里查看

了解和管理MacBook的开机自动启动项,是优化系统启动速度和运行效率的好方法。下面我来为你介绍几种查看和管理这些启动项的方法。查看和管理MacBook启动项1.通过系统设置(最简单直接的方法)...

想让电脑自己到点开机和关机?这4个超实用的设置方法快收好!

嘿,你是不是也经常忙到忘记关电脑?或者早上想用电脑时发现还没开机?别慌,今天我就跟你分享几个超实用的方法,帮你轻松搞定电脑的定时开关机设置。不管你是电脑小白还是有点基础,这篇教程都能让你秒懂操作,省时...

定时关机这样操作小白也会 一招设定工作日关机 指定时间关机

在日常使用电脑的过程中,我们常常会遇到这样的情况:晚上睡觉前忘记手动关机,导致电脑整夜运行,既浪费电又缩短硬件寿命;或者在下载大文件时,需要等待很长时间才能完成,却不能一直守在电脑前,下载完成后也无法...

日本无线电操作证试题,这些问题你能答的上来吗?

一直以来,我们对于日本的业余无线电的印象都停留在“操作能力强,爱好者数目众多”上,然而我们对于他们的业余无线电体系所知甚少。日本业余无线电操作证的等级分作四级,最基本的四级操作证书具有8MHz以下、2...

你知道吗?单边带信号就像DNA分子一样!

我们在准备B级操作证书的过程中,避免不了的要接触到一个新的名词——SSB。单边带是传统AM模式的一种特殊的形式,在传送相同的信息的过程中,其占用的带宽仅为AM模式的一半,那么SSB模式到底是怎样的一种...

取消回复欢迎 发表评论: