SQM 与智能队列限速

带宽再高,家里有人开始上传大文件,游戏和视频会议照样卡得没法用。这不是宽带不够快,而是出口队列里积压了太多包,学名叫缓冲膨胀(bufferbloat)。SQM(Smart Queue Management,智能队列管理)就是 OpenWrt 上解决这个问题的标准方案。本篇从机制讲到配置,帮你把满载延迟压下来。

先理解缓冲膨胀

经典家庭场景:下行千兆、上行只有二三十兆。云盘备份持续上传时,瞬间就把上行出口占满了,路由器里来不及发出的包进入缓冲队列。队列按到达顺序发送(FIFO),游戏里的小数据包别的不会,只能跟着排队。积压 25 万字节在 20Mbps 出口上就要等大约 100 毫秒,积压翻倍就是 400 毫秒——小包本身只有 0.08 毫秒的发送时间,却要等前面的队伍慢慢走。

问题的根源不是缓冲本身——缓冲能吸收突发流量是好事——而是积压不消退。出厂路由器的缓冲通常很大,积压起来没完没了。SQM 的思路就两条:把整形速率设得比实际出口略低,让积压发生在路由器可管理的队列里;同时用智能调度算法让小流量优先获得发送机会。

术语 含义
缓冲膨胀 队列长期积压导致的持续高延迟
流量整形 主动限制发送速率
按流调度 不同连接各占一条队列轮流发送
主动队列管理 积压时主动丢包/标记促发送端减速
IFB 接收方向整形用的虚拟接口

SQM 的两个核心组件是 CAKE 算法和 fq_codel 机制。CAKE 负责整形和分类,fq_codel 负责按流调度和队列管理,两者组合的预设方案 piece_of_cake 是官方推荐的新手起点。另有一个经典组合是fq_codel 单独使用(只做调度不整形),适合带宽充裕、只想缓解延迟的场景,但它无法约束超出实际速率的流量,家用场景还是带整形的完整方案更实用。

开始填速率之前,先确认家中宽带的实际上行能力。很多人只记得套餐的名义速率,30M 套餐实测可能只有 26 到 28。多时段测几次取稳定值,整形速率以实测为基准而不是以套餐广告为基准,效果会好得多。这一步偷懒,后面所有调优都是建在失真的数字上。

安装与基本配置

opkg update
opkg install sqm-scripts luci-app-sqm

安装后 LuCI 里出现 Network → SQM QoS 页面。基础配置只有四个关键项。开始填写之前,先弄清楚一个概念:SQM 的整形是分方向的。上行(上传)整形直接在 WAN 出口网卡上做,简单直接;下行(下载)整形稍绕,sqm-scripts 会把接收流量重定向到一个叫 IFB 的虚拟接口再按上行方式处理。所以界面上才有那个开启下行整形的开关——它带来的效果差别很大,占用 CPU 也更多,低配设备可以只开上行。

配置项 填什么 怎么填
启用 打勾 打勾
接口 出口设备名 PPPoE 拨号填 pppoe-wan
下行速率 实测下行 比实测略低,约九成
上行速率 实测上行 同上,约九成

接口选择是最容易出错的一项。不要照抄教程里的 eth0,用 ifstatus 或 LuCI 接口页看你的 WAN 实际设备名——PPPoE 环境下通常是 pppoe-wan。SQM 绑定错了接口,后续所有设置都无从谈起。

速率为什么设成实测的九成而不是满值:如果整形速率高于真实出口能力,路由器放出去的包照样在下游(光猫或运营商设备)排队,你管不到的地方继续堵。让整形速率略低于出口,积压就被转移到路由器内部这条你可以调度的队列上,SQM 才有用武之地。单位也容易踩坑:界面里是 kbit/s,1Mbps 等于 1000kbit/s,写错一个数量级限速就完全变味。另一个高频错误是直接用测速网站峰值的十进制写法——内存里记的是 30Mbps,手一抖填成 30(kbit/s),限速就变成了三十千比特每秒,慢到怀疑人生。填完默读一遍数字和单位,这个小动作能挡掉大量低级故障。

beginner 的标准流程是:先测速(有线连接,多时段各测几次取稳定值),填九成,启用 piece_of_cake 预设,观察满载延迟变化,再慢慢细调。

效果验证与调优

有没有用,要靠对照实验说话,不能凭感觉。

第一步,找一台有线电脑,持续 ping 一个稳定的外网目标(比如公共 DNS),记录空闲时的基准延迟。第二步,启动一个能占满上传的任务,观察稳定满载一两分钟后的延迟变化。第三步,开启 SQM,重复同样的负载测试,对比延迟下降了没有。建议至少做三轮开关对照,避免把线路本身的波动误判成 SQM 的功劳。

有线是必选项: WiFi 本身的信道竞争和重传会把几十毫秒的抖动混进测量里,让你根本看不清 SQM 的真实效果。测试期间还要提醒家里其它设备别刷视频,否则测的不是整形效果而是家庭流量峰值。如果你发现无论如何延迟都很低,说明你家上行够用、压根不需要 SQM,配了反而是浪费 CPU——能得出这个结论同样是有价值的收获。

oa-0205

oa-0205

调优分两个方向。如果延迟改善了但峰值速率掉得太多,说明整形速率偏低或 CPU 吃不消,前者往上调速率,后者换硬件或降预设复杂度;如果速率没掉但延迟没改善,多半是整形速率仍高于实际出口,或者硬件转发绕过了 CPU 队列——流量卸载(flow offload)开启时数据包不经 CPU 处理,SQM 自然管不到,调 SQM 期间建议先关掉它再观察。

先解释一下新手 presets 的选择逻辑。piece_of_cake 是最简单的一种 CAKE 配置:不做任何分类,所有流量一视同仁做按流调度和队列管理,满足绝大多数家庭需求。layer_cake 进一步按三层区分(优先报文/视频/尽力而为),适合你想保证游戏包绝对优先的场景;classful 选项留给有明确定制需求的用户,性能开销最大。从 piece_of_cake 开始看效果,再决定要不要升级预设复杂度,是官方反复推荐的路线。

还有一个设备公平性的进阶选项:CAKE 可以按源主机分队列,防止某台下载机一个人占满整条出口。在 LuCI 高级设置里打开对应选项即可,这个设置对合租和多人家庭尤其有用。多 WAN 环境下,每条线路要分别配置 SQM,配合《多 WAN 与负载均衡》一章的接口结构逐线路设置,操作时分清两个整形器不要叠加在同一条线路上。对称线路和 PPPoE 线路还要留意 overhead 补偿设置,把封装开销算进去,整形速率才精确。

一个典型的调优过程

举一个具体例子把流程串起来。某家庭下行 500Mbps、上行 30Mbps,原状态是有人上传时全家游戏卡顿。第一步有线测速三次取稳定值:上行确实只有 28Mbps,说明名义 30M 名不副实。第二步 SQM 上行设 25200kbit/s(九成),下行先关(行方向推干扰主要靠上行整形)。第三步开两台设备,一台跑上传占用,一台测延迟,发现满载 ping 从 180ms 降到 22ms,核心问题解决。第四步:下行方向开了 SQM 后峰值从 500M 掉到 430M,但家里下载机常驻跑满,俩需求冲突——最后决定下行不开 SQM,只保留上行整形,换取下载速率不受影响。

这个过程展示了两个原则:问题定位在上行就优先解决上行,不盲目全开;速率和延迟的权衡按自家使用习惯来,没有标准答案。关于如何长期监控这些指标是否稳定,系统日志与监控 一章介绍了 collectd 图表化监控的搭建方法。

典型家庭带宽上下行对比

硬件限制与取舍

SQM 不是免费的午餐。整形和调度需要逐包处理,对 CPU 要求很高:普通百元路由器跑千兆 SQM 基本没戏,x86 软路由或高性能 ARM 才能跑满高速线路。判断你的设备扛不扛得住,满载时 top 看 CPU 占用即可,接近满载就说明瓶颈在这。

为什么家用环境特别需要 SQM 而企业网络很少提它?因为家庭宽带上下行严重不对称,上行只有下行的几十分之一,出口越窄越容易积压。企业专线上下行对称且带宽充裕,缓冲膨胀感受不明显。同理,家里上行动辄几百兆的话,问题紧迫性会低很多。判断自家是否需要 SQM,看上行是否常被占满,而不是看下行有多高。

还有一个反直觉的现象值得记住:SQM 会主动丢一部分包。这些是队列管理算法有意为之的控制信号,促使 TCP 发送端自我减速,和线路故障造成的丢包是两码事。看到开启 SQM 后接口统计有几个丢包不用紧张,结合应用体验一起看——只要延迟稳了、网速正常,那几个丢包恰恰是算法在工作的证据。

成本与收益要一起算。开启 SQM 后测速峰值可能下降几个百分点,换来的是满载时稳定的低延迟。对大多数同时有下载和游戏需求的家庭,这个交换很划算;如果只是一个人看看视频、从不满载,那确实没必要折腾。硬件性能的上限在哪里,可以参考 软路由性能 的实测数据再决定。

整形速率与延迟的关系

延伸阅读

  • 《性能优化:CPU 与无线调优》:SQM 之外的转发性能提升手段。
  • 《多 WAN 与负载均衡》:多线路环境下的限速组织方式。
  • 《系统日志与监控》:用监控数据量化 SQM 前后的延迟变化。