Matrix 首页推荐
Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。
文章代表作者个人观点,少数派仅对标题和排版略作修改。
在无线路由器的设置页面上,我们可能会看到一个名为「智能队列」的功能(根据品牌或操作系统的不同,也可能会被称做「智能 QoS」、「SQM」等)。
这一功能是如何工作的?是否能让网速变快?是否需要打开?本文将尝试解答这些问题。
从「网络如何连接」说起
本章节主要介绍计算机网络的基础知识。如果读者已经熟悉相关知识,可跳过这部分内容。
在介绍「智能队列」之前,先来了解一下基础的网络知识。
两台电脑间进行数据传输,存在两种方式,分别是电路交换和分组交换 。
对于电路交换 ,两台电脑独占一条线路进行数据传输。过去的固定电话,大多使用的就是电路交换。
由于独占一条线路,两台设备之间的通信较为稳定,很难出现数据丢失、数据传输顺序错乱等情况。但一条线路只能供一组电脑使用,另外一组电脑想要通信,就不能复用原来的线路了。
对于分组交换 ,传输的数据被拆分为小段,每一小段叫做一个数据包(报文)。数据以报文的形式进行转发,从而实现了多组电脑复用一条线路进行通信。
电路交换虽然能保证数据传输的稳定性,但由于独占线路浪费太多资源,所以在 Internet 中,使用的是分组交换 。
分组交换将数据拆分成一个一个的小片段来转发,没有独占线路。如果网络条件不好(例如同时有大量报文经过路由器,超出了路由器的处理能力),很有可能遇到数据顺序错乱、甚至数据丢失等情况。那么,这些情况应该如何避免?
- 在微信视频通话 、 电视直播等应用中,报文的丢失或乱序,只会造成视频图像卡顿,不会造成太严重的影响。所以这些应用会使用简单的 UDP 协议,不考虑丢包、乱序。
- 在网页浏览 、 文件下载等应用中,一般使用基于 TCP 的 HTTP 协议。TCP 在报文中携带序号,避免乱序;同时提供了报文的丢失重传机制,避免了丢包。所以,也可以认为 TCP 为两台电脑的应用程序建立了一个虚拟的「连接」。(最新版本的 HTTP/3 协议,使用的则是 QUIC。QUIC 虽然基于 UDP,但引入了与 TCP 类似的报文丢失重传机制)
如果想要了解更多网络基础知识,推荐阅读「入网指南」系列文章:
- 入网指南 01 | 一文读懂你身边的「网络」
- 入网指南 02 | 当你发消息的时候,发生了什么
- 入网指南 03 | 交换机在交换什么?
- 入网指南 04 | IP 地址大揭秘
- 入网指南 05 | 除了接线,还有什么影响着我们网上冲浪
- 入网指南 06 | 连上 Wi-Fi 就能上网了吗?
网络延迟:影响上网体验的重要因素
带宽和延迟 ,是影响上网体验的两大因素。
带宽指的是在单位时间内,网络最多能传输多少数据。
网络的带宽和水管的粗细有着很多相似之处,水管越粗,相同时间流出的水越多;同样地,网络带宽越大,相同时间能够传输的数据越多。
在日常上网过程中,大的带宽能带来这些好处:
- 上传、下载文件的速度更快
- 在线看视频时,缓冲的时间更短
- 如果家中有多个人同时上网,大的带宽能够保证每个人都能流畅上网,相互的影响更小
对于家庭宽带,我们常常听到的 10 兆、50 兆、100 兆、千兆,就是指的带宽的大小。
延迟指的是数据从网络的一端到达另一端,所需要的时间。
过大的延迟也会对上网体验带来不好的影响,例如:
- 在浏览器中输入网址敲回车后,需要等更长的时间,网页才能加载;
- 视频聊天、语音通话质量变差,甚至能直接感受到声音、画面的滞后;
- 玩在线游戏时,发现游戏变慢变卡。
在很多时候,延迟相比带宽更容易被人感知,对网络体验的影响更大。
是什么导致了网络延迟?
上文中介绍过,Internet 使用的是分组交换 。如果大家阅读过计算机网络相关的书籍,应该对分组交换的「存储-转发」机制有一定的印象。
简单说,「存储-转发」是指网络设备将收到的报文存储在缓冲区 ,然后再发送。
这是由于网络设备的性能有限,转发报文有速率限制。如果设备短时间内收到大量报文,一时半会儿处理不过来,就可以先报文存起来,空闲时慢慢发送 。通过「存储-转发」,能够提高网络设备的吞吐量,更充分地利用带宽 。
其中,存储报文缓冲区,是一个先进先出的队列 。那么,队列的长度应该如何确定?是不是队列越长,能够存储的报文越多,网络的性能就越好?大家可以先思考下这个问题。
其实在过去,内存价格比较昂贵,考虑到成本,网络设备的队列不会太大。现在,随着内存价格的下降,网络设备拥有了更大的队列。
但是,网络的带宽是有限的。实际的可用带宽,取决于数据传输路径上的最小带宽。这个最小带宽也被称做带宽上的「瓶颈」(bottleneck)。
由于瓶颈的存在,如果流量长时间以较大速率发送,大的队列并不能显著提升吞吐量。相反,大量报文滞留在队列中,会带来延迟的增大 。
这种队列中缓存有大量报文,来不及发送,导致数据传输延迟增大的现象,被称做 bufferbloat(缓冲区膨胀)。
DSLReport 提供的测速服务,能够检测网络的 bufferbloat 程度。不过由于没有中国大陆服务器,测试结果不够准确。国外的读者可以尝试一下:
家用无线路由器中的 QoS 功能
在「智能队列」出现之前,很多家用路由器已经提供了 QoS 功能。那么,传统的 QoS 如何解决网络延迟、网络拥堵?存在哪些不足之处?
在了解这个问题之前,先来熟悉一下网络中的报文,是什么样子的:
在网络中传输的报文,一般包括了链路层、网络层、传输层、应用层这 四层 信息。其中,网络层的源 IP 地址、目的 IP 地址、协议号 ,和传输层的源端口号 、目的端口号, 是 QoS 算法中常常会关注的五个信息。这些信息合称「五元组」。
同一个应用在同一时间段内,传输的报文中,这些信息一般是不会发生变化的。例如观看在线视频时,同一个视频的所有报文 ,一般拥有相同的五元组信息。所以,通过五元组,我们能够区分不同应用的流量。
特别地,一些常见的应用,会使用固定的端口号。例如网页浏览一般使用 80、443 端口;英雄联盟游戏,使用的是 5000-5500 端口 ......
所以,当我们想要提升英雄联盟游戏的体验时,在路由器上设置让 5000-5500 端口的报文优先通过即可:
家用路由器中常见的 QoS 功能,就是通过手动设置 IP 地址、协议号、端口号等报文特征来实现的。这种方式需要用户了解一定的网络知识,且操作复杂。(虽然部分无线路由器内置了常用应用的 QoS 规则,但仍需要一定的手动设置,且无法及时适配新的、小众的应用)
当然,除了上文中介绍的内容,QoS 还有多种不同的实现方式。例如:
- 对特定应用(例如 BitTorrent)进行限速
- 按照 MAC 地址指定某台设备的优先级(例如提高 Nintendo Switch 的优先级,使游戏更加流畅)
- 通过 WMM、DSCP 等机制来决定报文优先级
这些机制各有各的特色和不足。例如对应用程序限速的方式,虽然效果明显,但无法在网络空闲时,动态利用剩余带宽来提升传输速度,也难以适应带宽频繁变化的无线网络。关于上述 QoS 机制的技术细节,本文不再详细介绍。如果感兴趣,可以搜索相关关键词,进一步了解。
智能队列:通过「全自动」的方式优化网络、降低延迟
什么是「智能队列」
目前,一部分新的无线路由器,开始有了名为「智能队列」的功能。这一功能一般指的是 fq_codel。
fq_codel 包含两种队列管理机制,分别是 Flow Queue 和 CoDel。在下文中,我将简要介绍这两种机制的作用。
Flow Queue
前文中介绍过,网络中的报文一般都有自己的五元组信息;同一应用发送的报文,在一定的时间段内,五元组信息是相同的 。这些信息相同的一系列报文,被称做一条流(flow)。
Flow Queue 为每条流单独维护一个队列。例如,如果我们一边在线观看视频,一边进行语音通话,一边玩游戏,Flow Queue 就会为视频播放的流量、语音通话的流量、在线游戏的流量各维护一条队列:
正常情况下,在线观看视频需要占用较大的带宽,但对延迟不敏感,用户可以容忍几秒甚至几十秒的缓冲时间。
而语音通话和在线游戏占用带宽小,但对延迟敏感。例如语音通话时,如果一个人说了一句话,对方在几秒后才能听到,用户就能明显感知到延迟。
如果三种应用共用一个队列,队列中会充满大量视频播放应用的报文,导致语音通话、在线游戏的报文迟迟无法发送,增大了这两种应用的延迟。
Flow Queue 为视频播放、语音通话、在线游戏各维护一条队列,并公平地调度三个队列,避免视频播放的报文占用太多时间,从而让在线游戏、语音通话的报文得到及时处理。由于 Flow Queue 确保了应用程序之间的「公平」(fair),所以又被称做 Fair Queue。
CoDel
我们已经知道,适当长度的队列,能够充分利用带宽、提高吞吐量。但过长的队列,又会导致过大的延迟。也就是说,队列既不能过长、也不能过短。
CoDel 所做的,就是让队列维持在合适长度 ,最大限度地提升网络性能。
CoDel 通过计算报文在队列中的停留时间,来判断队列是否过长。具体做法如下:
- 报文进入队列时,在报文上记录当前时间(也就是报文入队时间)
- 报文出队列时,再次获取当前时间(报文出队时间)
- 计算报文入队时间与出队时间的差值 ,即可得到报文在队列中停留的时间
- 当报文在队列中的停留时间超过阈值,说明队列过长,需要缩小队列长度
当队列过长时,CoDel 会直接丢弃出队列的报文,从而减少队列中报文的数量,达到控制队列长度的效果。(这种对报文的丢弃,并不会对网络带来负面影响,具体请见后续章节)
可以看出,CoDel 根据队列中报文的停留时间 ,来决定是否丢弃报文。而不是「一刀切」地将队列限制在一个固定的、较小的长度。这样既能降低延迟,又保留了队列最大的优点:吸收短暂的大流量报文、提升吞吐量。
另外,我们的设备,尤其是手机等移动设备,所处的网络环境是复杂多变的。例如手机靠近或远离无线路由器,就有可能导致网络带宽的变化。CoDel 通过计算报文停留时间的方式控制队列,能够更加灵活地适应网络带宽、网络质量的变化。
fq_codel
Flow Queue 确保了不同应用程序的流量能够公平传输。CoDel 控制队列长度,实现了整体延迟的降低。fq_codel 就是将 Flow Queue 和 CoDel 结合在一起使用的机制。
其中,Flow Queue 先将不同的流划分为不同的队列,再为每一个队列使用 CoDel,控制报文的延迟。两者结合使用,共同提升网络体验。
fq_codel 具有免配置、天然适应不同的网络环境、实现简单、消耗资源少等特色,越来越多的无线路由器(以及开源的路由器操作系统),开始内置这一机制。
参考 KoolShare 上的这篇帖子,作者经过测试,发现打开 fq_codel 之后,在 BT 下载占满上行带宽时,在线游戏依旧保持较低的延迟:
- 可能是家庭路由里最好的 QoS——在线游戏者的福音 - KoolShare (见 8 楼、10 楼、22 楼、25 楼的测试结果)
是否需要打开「智能队列」?
前面介绍了 fq_codel 的一系列优点。那么,fq_codel 有没有缺点?是否需要我们打开?
我的设备 CPU 性能不强,是否可以打开「智能队列」?
根据这篇帖子,ER-X 路由器在打开 fq_codel 时,最大支持 200M 左右的带宽。
ER-X 使用的是 MT7621 CPU。从 这个页面 可以看到,我们熟悉的小米路由器 Pro、斐讯 K2P 等,都采用了这一系列的 CPU。也就是说,如果宽带带宽小于 200M,使用这些路由器,「智能队列」对网速基本不会有太大影响。
不过在家用路由器上,不同人有着不同的方案:从百元以下、到千元以上的无线路由器,都有不少人在使用;还有一些人使用有线路由器、软路由,甚至企业级网络设备。
不同的设备,在 CPU 性能上存在很大的差异。还有一些设备,虽然 CPU 性能较弱,但使用了专门的硬件来处理报文。对于 CPU 性能不足的设备,一旦打开了「智能队列」,CPU 就需要参与更多的运算来处理报文,影响报文转发速度。
虽说 fq_codel 是一个简单的算法,占用 CPU 资源相对较少。但考虑到家用网络设备的多样性,还是需要经过实测,才能决定是否要打开该功能。
我家的宽带速度较快(100M 以上),是否还有必要开启「智能队列」?
很多人已经用上了 200M、500M 甚至 1000M 的宽带。而大部分应用跑不满这么大的带宽,即使家里的多个人一起用宽带,也很难把带宽占满。对于这样的宽带,是否有必要开启「智能队列」呢?
大部分家庭宽带,上传和下载带宽是不对等的。例如一个 200M 的宽带,上传带宽可能只有 20M。而很多协议需要客户端和服务端的双向交互(例如 TCP,接收端要向发送端发送确认报文),如果上传速度受到限制,也会影响到下载速度 。
所以对于下载带宽大,但上传带宽小的环境,使用「智能队列」也有利于提升上网体验。
但是,流量速率越快,fq_codel 处理报文消耗的 CPU 资源也就越多。如果带宽较大,CPU 可能处理不过来大速率的报文。所以,最终还是要综合考虑宽带带宽,和网络设备的 CPU 性能 ,来决定是否要打开「智能队列」。
「智能队列」会主动丢弃报文,会不会对网络造成负面影响?
fq_codel 控制队列长度,是通过主动丢弃报文来实现的。或许读者们会有疑问,主动丢包是否会对网络有负面影响?是否会导致传输数据的缺失?
其实,Internet 被设计成分组交换的方式,丢包是很常见的现象。对于视频通话等使用的 UDP 协议的应用,少量丢包不会有太大的影响;对于网页浏览等应用使用的 TCP 协议,其本身的重传机制,也能确保数据全部正确传输。
另外,TCP 协议还拥有拥塞控制机制,能够自动调整数据发送速率。大部分拥塞控制算法在检测到丢包时,能够自动降低发送速率。所以,fq_codel 的丢包,还可以反馈到 TCP,让 TCP 协议主动降低数据发送速率,进一步缓解 bufferbloat。
总之,fq_codel 的丢包并不会对网络带来太多负面影响。
结论
在网络设备的 CPU 性能足够的情况下,打开「智能队列」,能够在一定程度上提升上网体验。推荐有条件的用户打开该功能。
但是,如果家庭网络环境特殊,例如路由器性能差、上下行带宽都非常充足等情况,fq_codel 的作用就没有那么大了。如果不确定是否需要打开,还是建议亲自测试一下,观察该功能对上网体验的影响。
参考资料与延伸阅读
在常用的无线路由器操作系统上设置 fq_codel:
- OpenWrt/LEDE: https://openwrt.org/docs/guide-user/network/traffic-shaping/sqm
- Asuswrt-Merlin: https://github.com/RMerl/asuswrt-merlin.ng/wiki/QoS-Queue-Disciplines
- dd-wrt: https://forum.dd-wrt.com/wiki/index.php/QoS
- padavan/rt-n56u: 可参考此脚本设置 https://github.com/StarWhiz/Asus-RT-AC1200-Padavan/blob/master/fq_codel%20script%20for%20Asus%20AC1200.txt
- Ubiquiti EdgeRouter: https://help.ui.com/hc/en-us/articles/220716608-EdgeRouter-Quality-of-Service-QoS-Advanced-Queue
- Linux: https://www.b1c1l1.com/blog/2020/03/26/linux-home-router-traffic-shaping-with-fq_codel/
CAKE 是一种新的队列管理机制。它吸收了 fq_codel 的优点,并在 fq_codel 的基础上增加了更多新特性。如果自己的路由器支持 CAKE,建议直接用 CAKE 代替 fq_codel:
- Cake - Bufferbloat.net
- Piece of CAKE: A Comprehensive Queue Management Solution for Home Gateways
- Cake - Comprehensive Queue Management Made Easy + Slides - BatteMeshV8 - YouTube
如何进一步优化家庭网络、降低网络延迟:
- Introduction - StopLagging.com(一个以降低网络延迟、避免 bufferbloat 为主题的个人博客)
- How I Maximized the Speed of My Non-Gigabit Internet Connection (Speedtest by Ookla 工程师如何优化自己的家庭网络)
- INCREASE BROADBAND SPEED Tips and Guides
fq_codel 基础知识:
- RFC 8289 - Controlled Delay Active Queue Management(CoDel 的 RFC 文档)
- RFC 8290 - The Flow Queue CoDel Packet Scheduler and Active Queue Management Algorithm (fq_codel 的 RFC 文档)
- Controlling Queue Delay - ACM Queue
- Cgroup - Linux 的网络资源隔离 | Zorro’s Linux Book(本文是一篇关于 cgroup 的文章,但文章内也对 fq_codel 做了详细介绍)
关于 Bufferbloat 的更多介绍:
本文介绍了 Linux 网络协议栈中的「队列」。通过阅读本文,可以更清晰地了解报文在网络设备内部是如何处理的:
传统的 TCP 拥塞控制算法倾向于填满队列,可能会加剧 bufferbloat。所以除了 fq_codel,还可以通过优化 TCP 拥塞控制算法,来缓解 bufferbloat。最近几年流行的 TCP BBR,就是一种新的拥塞控制算法:
- 为什么 TCP 协议有性能问题 - 面向信仰编程
- Socket 缓存究竟如何影响 TCP 的性能? | Zorro’s Linux Book
- BBR: Congestion-Based Congestion Control | Queue
- Linux Kernel 4.9 中的 BBR 算法与之前的 TCP 拥塞控制相比有什么优势?
- 漫谈 TCP-AIMD/BBR 的公平性以及 buffer bloat
本文图片素材来自 www.flaticon.com,作者分别是 Freepik、srip、surang、xnimrodx、Vitaly Gorbachev、photo3idea_studio。题图来自 Unsplash,作者是 Jonathan。
我对 fq_codel 的了解还不够深入。如果发现文章中有错误,请在评论区留言指正。
对于家庭网络的更多内容,可关注我在 GitHub 上创建的 Awesome List。欢迎提交 issue 和 pull request:
> 下载少数派 客户端 、关注 少数派公众号 ,了解更妙的数字生活 🍃
> 想申请成为少数派作者? 冲!