在无线路由器的设置页面上,我们可能会看到一个名为「智能队列」的功能(根据品牌或操作系统的不同,也可能会被称做「智能QoS」、「SQM」等)。
这一功能是如何工作的?是否能让网速变快?是否需要打开?本文将尝试解答这些问题。
在介绍「智能队列」之前,先来了解一下基础的网络知识。
两台电脑间进行数据传输,存在两种方式,分别是电路交换和分组交换。
由于独占一条线路,两台设备之间的通信较为稳定,很难出现数据丢失、数据传输顺序错乱等情况。但一条线路只能供一组电脑使用,另外一组电脑想要通信,就不能复用原来的线路了。
对于分组交换,传输的数据被拆分为小段,每一小段叫做一个数据包(报文)。数据以报文的形式进行转发,从而实现了多组电脑复用一条线路进行通信。
电路交换虽然能保证数据传输的稳定性,但由于独占线路浪费太多资源,所以在Internet中,使用的是分组交换。
分组交换将数据拆分成一个一个的小片段来转发,没有独占线路。如果网络条件不好(例如同时有大量报文经过路由器,超出了路由器的处理能力),很有可能遇到数据顺序错乱、甚至数据丢失等情况。那么,这些情况应该如何避免?
带宽和延迟,是影响上网体验的两大因素。
在日常上网过程中,大的带宽能带来这些好处:
对于家庭宽带,我们常常听到的10兆、50兆、100兆、千兆,就是指的带宽的大小。
过大的延迟也会对上网体验带来不好的影响,例如:
在很多时候,延迟相比带宽更容易被人感知,对网络体验的影响更大。
简单说,「存储-转发」是指网络设备将收到的报文存储在缓冲区,然后再发送。
其实在过去,内存价格比较昂贵,考虑到成本,网络设备的队列不会太大。现在,随着内存价格的下降,网络设备拥有了更大的队列。
但是,网络的带宽是有限的。实际的可用带宽,取决于数据传输路径上的最小带宽。这个最小带宽也被称做带宽上的「瓶颈」(bottleneck)。
这种队列中缓存有大量报文,来不及发送,导致数据传输延迟增大的现象,被称做bufferbloat(缓冲区膨胀)。
DSLReport提供的测速服务,能够检测网络的bufferbloat程度。不过由于没有中国大陆服务器,测试结果不够准确。国外的读者可以尝试一下:
在「智能队列」出现之前,很多家用路由器已经提供了QoS功能。那么,传统的QoS如何解决网络延迟、网络拥堵?存在哪些不足之处?
在了解这个问题之前,先来熟悉一下网络中的报文,是什么样子的:
特别地,一些常见的应用,会使用固定的端口号。例如网页浏览一般使用80、443端口;英雄联盟游戏,使用的是5000-5500端口......
所以,当我们想要提升英雄联盟游戏的体验时,在路由器上设置让5000-5500端口的报文优先通过即可:
家用路由器中常见的QoS功能,就是通过手动设置IP地址、协议号、端口号等报文特征来实现的。这种方式需要用户了解一定的网络知识,且操作复杂。(虽然部分无线路由器内置了常用应用的QoS规则,但仍需要一定的手动设置,且无法及时适配新的、小众的应用)
当然,除了上文中介绍的内容,QoS还有多种不同的实现方式。例如:
目前,一部分新的无线路由器,开始有了名为「智能队列」的功能。这一功能一般指的是fq_codel。
fq_codel包含两种队列管理机制,分别是FlowQueue和CoDel。在下文中,我将简要介绍这两种机制的作用。
FlowQueue为每条流单独维护一个队列。例如,如果我们一边在线观看视频,一边进行语音通话,一边玩游戏,FlowQueue就会为视频播放的流量、语音通话的流量、在线游戏的流量各维护一条队列:
而语音通话和在线游戏占用带宽小,但对延迟敏感。例如语音通话时,如果一个人说了一句话,对方在几秒后才能听到,用户就能明显感知到延迟。
如果三种应用共用一个队列,队列中会充满大量视频播放应用的报文,导致语音通话、在线游戏的报文迟迟无法发送,增大了这两种应用的延迟。
我们已经知道,适当长度的队列,能够充分利用带宽、提高吞吐量。但过长的队列,又会导致过大的延迟。也就是说,队列既不能过长、也不能过短。
CoDel所做的,就是让队列维持在合适长度,最大限度地提升网络性能。
当队列过长时,CoDel会直接丢弃出队列的报文,从而减少队列中报文的数量,达到控制队列长度的效果。(这种对报文的丢弃,并不会对网络带来负面影响,具体请见后续章节)
FlowQueue确保了不同应用程序的流量能够公平传输。CoDel控制队列长度,实现了整体延迟的降低。fq_codel就是将FlowQueue和CoDel结合在一起使用的机制。
其中,FlowQueue先将不同的流划分为不同的队列,再为每一个队列使用CoDel,控制报文的延迟。两者结合使用,共同提升网络体验。
fq_codel具有免配置、天然适应不同的网络环境、实现简单、消耗资源少等特色,越来越多的无线路由器(以及开源的路由器操作系统),开始内置这一机制。
参考KoolShare上的这篇帖子,作者经过测试,发现打开fq_codel之后,在BT下载占满上行带宽时,在线游戏依旧保持较低的延迟:
前面介绍了fq_codel的一系列优点。那么,fq_codel有没有缺点?是否需要我们打开?
不过在家用路由器上,不同人有着不同的方案:从百元以下、到千元以上的无线路由器,都有不少人在使用;还有一些人使用有线路由器、软路由,甚至企业级网络设备。
不同的设备,在CPU性能上存在很大的差异。还有一些设备,虽然CPU性能较弱,但使用了专门的硬件来处理报文。对于CPU性能不足的设备,一旦打开了「智能队列」,CPU就需要参与更多的运算来处理报文,影响报文转发速度。
虽说fq_codel是一个简单的算法,占用CPU资源相对较少。但考虑到家用网络设备的多样性,还是需要经过实测,才能决定是否要打开该功能。
很多人已经用上了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:
CAKE是一种新的队列管理机制。它吸收了fq_codel的优点,并在fq_codel的基础上增加了更多新特性。如果自己的路由器支持CAKE,建议直接用CAKE代替fq_codel:
如何进一步优化家庭网络、降低网络延迟:
fq_codel基础知识:
关于Bufferbloat的更多介绍:
本文介绍了Linux网络协议栈中的「队列」。通过阅读本文,可以更清晰地了解报文在网络设备内部是如何处理的:
传统的TCP拥塞控制算法倾向于填满队列,可能会加剧bufferbloat。所以除了fq_codel,还可以通过优化TCP拥塞控制算法,来缓解bufferbloat。最近几年流行的TCPBBR,就是一种新的拥塞控制算法: