如果只用一条队伍排队,那么排在最前面的那个人一旦卡住,
后面所有人——哪怕他们要去的窗口空着——都得干等。
这就是网络世界里最昂贵的一种浪费:队头阻塞(Head-of-Line Blocking)。
它会让一台理论上 100% 能力的交换机,实际只跑出约 58.6% 的吞吐。
VOQ(Virtual Output Queue,虚拟输出队列)就是解决这个问题的答案。
这份白皮书不会先告诉你结论,而是带你从"为什么一定会拥塞"这个最原始的物理事实出发,
一步步把 VOQ 推导出来——推导完你会发现:它几乎是唯一合理的答案。
我的写作信条是:逻辑让人信服,故事让人行动。所以这篇文章不采用"先定义、再罗列特性"的说明书写法, 而是采用苏格拉底提问法——我只负责提问和拆解,答案由你自己"想出来"。 每一章的结构固定为四步:
图 0-1 本文的认知阶梯:四步一循环,共七级台阶。
三个不可回避的物理事实:端口速率有限、流量是突发的、多个入口会抢同一个出口。结论:缓存或丢包,二选一。
是最理想的——理想到物理上买不起。它要求内存带宽是端口速率的 N 倍甚至 (N+1) 倍。
队头阻塞(HOL Blocking)把吞吐锁死在 58.6%。这就是你一直困惑的那个"为什么"。
一句话:把入口的"一条队"拆成"N 条队",每条队只服务一个出口。物理在入口,逻辑在出口。
Request / Grant / Accept 三次握手、信用(Credit)机制、iSLIP 调度器、可交互演示。
N² 队列膨胀、调度器复杂度、额外的调度延迟、深缓冲的"缓冲膨胀"争议。
从 Crossbar + 集中调度,到 CloudScale ASIC 的分布式 VOQ、无损以太网(PFC/ECN)与 AI/ML 数据中心。
真正理解一项技术,不是记住"它是什么",而是重现"人们当年是被什么逼到必须发明它"。
——本文的方法论前提假设我给你一台"完美"的交换机:转发表查询零延迟、内部线路无限快、ASIC 芯片快到不需要等待。 请问——这台完美交换机里,还需要"缓冲区(Buffer)"和"队列(Queue)"吗?
大多数人的第一反应是"不需要,既然什么都无限快"。请在往下读之前,先停三秒。 如果答案是"需要",那么需要它的理由,一定与芯片快不快无关——那会是什么理由?
第一性原理的做法,是把对象拆到不能再拆、且无法被工程手段绕过的物理事实为止。 一台以太网交换机的工作本质只有一句话:把从某个入口进来的比特,搬到正确的出口上去。 围绕这句话,有三个事实是任何厂商、任何芯片工艺都无法取消的:
一个 400G 端口,每秒最多只能"吐出" 4×1011 比特。这是由物理层的 SerDes 时钟、调制方式和线缆决定的硬上限,不能因为"今天流量大"就临时提速。
没有任何机制让全世界的服务器"排好班"再发包。真实流量是 突发(Burst)的: 平均利用率可能只有 30%,但在某个 10 微秒里瞬时速率能顶到 300%。
这是交换机存在的意义带来的必然副作用:它是"多对多"的汇聚点。只要有 2 个以上入口, 就存在两包同一时刻都想去同一个出口的可能,即 竞争(Contention)。
把 A、B、C 三条放在一起,会推出一个不需要任何工程知识就能承认的结论: 在某些瞬间,想出去的数据量 > 能出去的数据量。而那些"想出去但暂时出不去"的比特, 在物理世界里只有两个下场——
图 1-1 拥塞的本质是一道小学算术题:1200 Gbps 想进,400 Gbps 能出。剩下的 800 Gbps,要么存,要么丢。
缓冲区是交换机内部一块用于临时存放数据包的高速存储器(片上 SRAM 或外挂 HBM/DRAM)。
队列是加在这块存储器上的服务顺序规则(通常为 FIFO,先进先出), 它决定"谁先被送出去"。
一句话:缓冲区是空间,队列是秩序。缓冲区解决"放哪儿",队列解决"谁先走"。
跑道(出口端口)每 90 秒只能起飞一架飞机,这是刚性上限;但旅客(数据包)到达航站楼的节奏毫无规律。
候机厅 = 缓冲区:让早到的人有地方待着,而不是被赶出机场(丢包)。
登机广播顺序 = 队列规则:决定谁先上飞机。
候机厅再大也有极限——人一直只进不出,最终还是要拒之门外。这就是缓冲无法消灭拥塞、只能吸收突发的原因。
这是理解"缓冲不是越大越好、但必须够用"的关键计算。设定一个非常真实的 AI 训练场景:
第一步,算超额速率:流入 1200 Gbps − 流出 400 Gbps = 超额 800 Gbps。
第二步,算超额字节:800 Gbps × 1 μs = 800 Gb/s × 10-6 s = 800,000 bit = 100,000 Byte ≈ 100 KB。
结论:只是 1 微秒的三打一,就要吃掉约 100 KB 缓冲。 如果突发持续 10 μs,就是 1 MB。而一颗高密度交换 ASIC 的片上缓冲总量可能只有几十 MB, 却要被几十个端口共享——你立刻能理解为什么"缓冲怎么分配"是交换机设计的核心命题。
第三步,反推一个重要事实:缓冲只能吸收短暂的不匹配。 如果 3:1 的输入持续不断(稳态超额订阅),那么无论缓冲多大,最终都会被填满, 丢包只是时间问题。所以:
现在回到开头那个问题。答案是:需要,而且必须需要。 因为队列存在的理由与芯片快慢完全无关——它源于"出口速率有限"(事实 A)与"竞争不可避免"(事实 C)。 即使转发引擎快到无限,出口那扇门的宽度也没变。
反直觉但至关重要的一句话:拥塞不是交换机"性能不足"的症状,而是统计复用(Statistical Multiplexing)这一网络根本设计的必然产物。 我们之所以能用 400G 的上行链路承载 32 个 400G 服务器端口,正是因为赌定"它们不会同时满速"。 而队列,就是这场赌局的安全气囊。
| 编号 | 物理事实 | 如果没有它会怎样(反证) | 推导出的必然结果 |
|---|---|---|---|
| A | 出口端口速率有限、刚性 | 若出口可无限提速,任何流入都能立刻送出,永不需要缓存 | 存在"能送出的上限",超出即需处置 |
| B | 到达时间随机、突发 | 若到达完全均匀且低于线速,永不会超过上限 | 瞬时速率可远超平均速率,形成微突发 |
| C | 多入口竞争同一出口 | 若每个入口有专属出口(点对点直连),就没有交换机存在的必要 | 竞争是"多对多汇聚"的固有代价 |
| ∴ | A ∧ B ∧ C ⇒ 瞬时"想出去的量" > "能出去的量" | 必须选择:缓存(Queue)或丢弃(Drop)。交换机设计的一切艺术,从这里开始。 | |
我们已经确立了"必须有队列"。但第一性原理还没走完,因为它只告诉我们"要存", 没告诉我们"存在哪儿"。而这个看似不起眼的位置问题,正是 VOQ 诞生的全部战场。 交换机的内部结构决定了只有三个可能的位置:
图 1-2 同一个"必须缓存"的结论,落在不同位置,会长出完全不同的三种交换机架构。
拥塞不是故障,是算术;队列不是补丁,是统计复用这场赌局必须配备的安全气囊。
—— 第一章金句上一章我们锁定了三个落脚点。直觉上最优雅的显然是出口排队: 谁堵在哪个门口,就在那个门口排队,天经地义、公平合理、互不干扰。 那么请回答——如果它这么完美,为什么全世界的高密度交换机都不是纯粹的输出排队?
提示:请不要从"逻辑"上找答案,逻辑上它无懈可击。请从"这块内存每秒要被读写多少次"这个角度想。 一台 64 端口 400G 的交换机,如果所有包都必须先塞进同一片出口缓冲,那片内存需要多快?
在批判一个方案之前,必须先精确理解它好在哪里。 纯输出排队(Pure Output Queuing,简称 OQ)的工作方式是:
一种交换机排队模型:交换网(Fabric)永不阻塞,任何入口的任何包都能在到达的同一时刻被立即传送到目的出口的缓冲区, 所有竞争仅在出口的队列中通过调度器裁决。
它是排队理论中的性能黄金标准(Gold Standard):在给定的到达序列下, OQ 能达成100% 吞吐, 且时延是理论最小值。学术界评价任何新架构,都是拿它去和 OQ 比"像不像"。
你一进航站楼,不用在大厅排队安检等号,而是被瞬间传送到自己航班的登机口候机厅坐下。 A 门再挤,也丝毫不影响 B 门的旅客准时登机。
每个门口自己排队、自己叫号、自己决定谁是头等舱先上(QoS)——完美隔离,互不干扰。
问题只有一个:这个"瞬间传送"是怎么实现的?如果 64 个入口的旅客同一秒全都要被传送到同一个 A 门, 那条传送带必须有64 倍的运力。这就是全部的代价所在。
现在做第一性原理的关键一步:把"瞬间传送"这个抽象说法,翻译成内存的读写次数。 因为在硅片上,"把包放进出口缓冲"这个动作没有任何魔法,它就是一次内存写入(Write); "把包从出口发出去"就是一次内存读取(Read)。
设交换机有 N 个端口,每个端口线速为 R(比如 400 Gbps)。考虑最坏情况:
N 个入口在同一个包时隙内,全部把包发往同一个出口 X。这在 AI 训练的
Incast(多打一)
场景中每天都在发生。那么在这一个时隙里,出口 X 的缓冲必须:
图 2-1 OQ 的理论优雅,在硅片上直接翻译成一张 (N+1)×R 的内存带宽账单。这不是"贵一点",而是物理上做不出来。
很多人以为内存瓶颈是"装不下",其实真正的瓶颈是每秒能被访问多少次。 以太网最小帧是 64 字节,在 400G 端口上,一个包最短只占约 1.3 纳秒。 要在 1.3 纳秒内完成 64 次写 + 1 次读,意味着单次内存访问必须在 20 皮秒(0.02 ns) 内完成。
而当前工艺下:
理论上可以做 65 端口的内存(65-port SRAM),但每增加一个读写端口, SRAM 单元的面积和功耗近似平方级增长。一颗 64×400G 的交换 ASIC 若这么做, 芯片面积和功耗都会超出光罩极限与散热极限数倍——它不是成本问题,是"造不出来"。
这是早期交换机的经典做法:所有端口共用一大块内存,写入时按目的端口挂链表。 但它的总带宽需求变成 2 × N × R(每个包进出各一次,且所有端口共享同一块内存)—— 比 (N+1)×R 更糟。共享内存架构因此只在低端口数、低速率的场景可行 (这也是为什么它常见于接入层小交换机,而绝不出现在核心/骨干平台)。
第一性原理的结论:OQ 不是被"工程师偷懒"抛弃的,
而是被SRAM 访问时间这条物理硬墙挡在门外的。
随着 N 和 R 每一代翻倍,这堵墙只会越来越高。
于是问题被迫改写成:能不能把缓冲搬到入口(那里只需 2×R 带宽),却仍然获得接近 OQ 的性能?
——这一问,就是 VOQ 的起点。
现在看另一个极端。如果把队列放在入口(Input Queuing,简称 IQ): 每个入口只服务自己这一个端口的流量,所以它的缓冲只需要承受1 次写入(自己端口进来的包)+ 1 次读取(被交换网取走)。
图 2-2 IQ 用"分而治之"解决了内存带宽问题:账单从 (N+1)×R 降到与 N 无关的 2×R。但它埋下了一颗更隐蔽的地雷。
IQ 并没有消灭问题,它只是把问题从"内存带宽"这个领域,搬到了"调度算法"这个领域。 因为现在交换网每个时隙每个出口只能接收一个包,必须有人来决定"这一时隙谁能过"—— 于是调度器(Scheduler)诞生了。 优秀的架构师看到这一步,会立刻警觉:被搬走的问题,往往会以更难缠的形式回来。
在进入第三章的"地雷"之前,先把三种模型摆在一张表上。请特别注意最后一行的 CIOQ——它是学术界给出的一个惊人结论,也是理解现代交换机为什么"够用"的关键。
| 模型 | 缓冲位置 | 内存带宽需求 | 吞吐性能 | 主要缺陷 | 现实中的地位 |
|---|---|---|---|---|---|
| OQ 纯输出排队 |
仅出口 | (N+1) × R | 100% (理论最优) |
随 N 线性增长的内存带宽需求,物理不可实现 | 性能标杆。只作为衡量其他架构的"理想参照系",以及低速小端口设备的实际方案 |
| IQ 单队列输入排队 |
仅入口 (每口 1 条 FIFO) |
2 × R | ≈ 58.6% (被 HOL 锁死) |
队头阻塞(HOL Blocking):出口空闲却无包可发,超 40% 能力被白白浪费 | 历史方案。因性能天花板过低,现代高性能设备已弃用 |
| VOQ 虚拟输出排队 |
入口 (每口 N 条队) |
2 × R | 100% (配好调度器) |
队列数量膨胀至 N²、调度器复杂、增加固定调度时延 | 当代主流。几乎所有现代高端交换/路由平台的基础架构 |
| CIOQ 组合输入输出排队 |
入口 + 出口 (含内部加速) |
2 × S × R S = 加速比 |
S = 2 时可 精确模拟 OQ |
需要交换网内部跑到 2 倍线速,出口也要缓冲,成本上升 | 工程最优解。现实产品多为 "VOQ + 小加速比 + 出口浅缓冲" 的混合体 |
定义 · 加速比(Speedup, S):交换网内部的运行速率相对于端口线速的倍数。
S = 1 表示内部与端口同速;S = 2 表示内部跑两倍速——
即在一个外部包时隙内,交换网可以完成两次内部传输。
Chuang、Goel、McKeown 与 Prabhakar(1999,Stanford)证明: 一台带 VOQ 的 CIOQ 交换机,只需加速比 S = 2, 配合合适的调度算法,就能精确模拟(exactly emulate)一台纯 OQ 交换机—— 不只是"吞吐相同",而是每一个包的离开时刻都完全一致。
它把交换机设计从一个"不可能问题"变成了一个"可控成本问题":
类比:这就像发现"要让全城车辆无堵塞通行,不需要把每条路都修成 64 车道, 只要把主干道修成 2 车道并配一套聪明的红绿灯"。从"扩容"转向"调度",是工程史上反复出现的胜利模式。
第二问的答案:没人纯粹做输出排队,不是因为它不好,而是因为它太好——
好到需要一片 (N+1)×R 带宽的内存,而这在物理上不存在。
于是工程界被迫退回到入口缓冲这条 2×R 的廉价路线上。
但请回看 图 2-2 右下角那个红色的"坏消息"。我们省下了内存带宽,却在入口留下了 "一个端口只有一条队" 这个结构。而队列的本质是先进先出(FIFO)—— 这意味着排在第二位的包,无论它要去哪里、目的地是否空闲,都必须等第一位的包先走。
如果入口队列的第一个包,想去一个正在被别人占用的出口; 而排在它后面的第二个包,想去一个完全空闲的出口—— 这一时隙里,会发生什么?
这台交换机会同时出现两个荒谬的现象:有包等着要走,有门空着没人用。 请为这个现象取个名字,并猜一猜——它到底浪费了多少性能?10%?20%?还是超过 40%?
最优雅的方案往往败于物理,而伟大的工程不是消灭权衡,是把权衡从"不可能"搬到"可负担"。
—— 第二章金句请你亲自当一次调度器。入口 1 的队伍里,第一个包要去出口 A(但 A 这一时隙被别人占了),
第二个包要去出口 B(B 完全空闲)。
队列的规则是先进先出(FIFO)——那么这一时隙,你能把第二个包放出去吗?
你不能。因为 FIFO 意味着"你只能看见队伍最前面那一个"。
结果就是这台交换机同时上演两个荒谬的画面:有包在等着走,有门空着没人用。
这不是 bug,这是结构决定的必然。
接下来我们要做两件事:给它一个名字,然后精确算出它到底吃掉了多少性能。
在一个先进先出(FIFO)的队列中,当队首元素因其所需资源不可用而无法被服务时, 队列中所有后续元素——即使它们所需的资源完全空闲——也被迫一同等待的现象。
它的根因不是"资源不足",而是"服务顺序被强制耦合": 一个队列只暴露一个"可服务点",于是不相关的请求被人为地串行化了。
关键判据:如果你观察到"资源空闲 + 请求等待"同时出现,那就是 HOL 阻塞。
你只买了一瓶水,扫码 3 秒就能走。可你前面那位大爷,推着满车货物,还要跟收银员理论优惠券。 旁边 4 号收银台空着无人——但你动不了,因为你在这条队里,而这条队只从头部放行。
注意这里的荒谬之处:收银台的总处理能力完全够用,被浪费掉的不是能力, 而是"把它用起来的机会"。这正是 HOL 阻塞最昂贵的地方—— 你买了 100% 的硬件,却只能兑现 58.6% 的价值。
一旦你掌握了这个判据(资源空闲 + 请求等待 = HOL),你会在整个 IT 世界里到处看见它。这也说明它的本质是数据结构层面的问题,而不是某个厂商的实现缺陷:
请记住这个模式:所有解法都长得一样——把"一条队"拆成"多条队",并允许乱序服务。 左转专用道、乱序执行、QUIC 的独立 Stream、以及我们即将推导出的 VOQ,本质上是同一个思想的四种化身。
抽象的定义不如一张解剖图。下图是最经典的场景:3 个入口的队首包恰好都想去出口 A (这在 AI 训练的 Incast 场景中不是巧合,而是常态)。请特别注意右侧被标红的两个出口。
图 3-1 HOL 阻塞的病理切片。请牢牢记住这句话:调度器的视野被 FIFO 挡住了。这就是 VOQ 要治的病。
光看图还不够。下面这个演示是一台真实运行的 3 端口输入排队交换机: 12 个包在 3 个入口排队,理想情况 4 个时隙就能全部送完(12 ÷ 3)。 请你点击"下一时隙",亲眼看看它实际用了几个时隙。
剧透一下结果:这台交换机需要 7 个时隙才能送完本该 4 个时隙送完的流量。 累计吞吐率 = 12 ÷ (7 × 3) ≈ 57.1%。 而这个数字,惊人地接近排队论给出的那个著名理论值——58.6%。 巧合吗?不是。下面我们把它算出来。
这个数字来自 Karol、Hluchyj 与 Morgan 于 1987 年在 IEEE Transactions on Communications 上发表的经典论文 《Input Versus Output Queueing on a Space-Division Packet Switch》。 它是整个交换机架构史上最重要的一个数字,因为它用数学宣判了单队列输入排队的死刑。 推导只需要三步,我保证不用任何超出高中数学的工具。
N → ∞(大规模交换机);这是整个推导中最漂亮的一步。既然 HOL 阻塞只由队首包决定(后面的包完全没有发言权), 那我们干脆只研究队首包的世界:
类比:这就像 N 个人同时冲向 N 个自助点餐机,每台每轮只能服务一人。 你一旦选定了某台,就不能改(因为 FIFO 已把目的地钉死),只能在那台前面老实排队。
在 N → ∞ 的极限下,对某个特定出口而言,"每时隙有多少个新的队首包指向我"这件事,
趋近于一个泊松过程(Poisson Process),平均到达率就等于我们要求的吞吐率 ρ。
而它的服务时间是确定的 1 个时隙(Deterministic)。
M/D/1 是什么?排队论的标准记号:
M(Markovian)= 到达是泊松随机的;D(Deterministic)= 服务时间固定;1 = 一个服务台。
M/D/1
的平均排队等待时间有现成公式:
对任一入口来说,一个队首包的完整生命周期是:先排队等 W 个时隙,再花 1 个时隙被传输。
所以它平均每 (1 + W) 个时隙才能送出 1 个包。而"每时隙送出的包数"就是吞吐率 ρ:
现在我们有两个式子、两个未知数(ρ 和 W),代入即可:
吞吐率必须小于 1,所以取减号:
这不是"某厂芯片没优化好",而是数学定理:
只要你坚持"每个入口一条 FIFO",那么无论你的交换网多快、缓冲多大、芯片工艺多先进,
你都别想突破 58.6%。
翻译成采购语言:你花钱买了一台 12.8 Tbps 的交换机,实际只能用出 7.5 Tbps。
剩下的 5.3 Tbps 不是被别人偷走了,是被"队列结构"吃掉了。
有人会问:58.6% 是 N→∞ 的极限,小交换机是不是好一些?确实好一些,但下滑得非常快, 而且刚过 8 个端口就基本贴上了极限值。请看这条令人沮丧的曲线:
图 3-2 只要 8 个端口,吞吐率就已跌到 61.5%,与 58.6% 的理论下限相差不足 3 个百分点。而今天一颗 ASIC 动辄 64~256 个端口。
| 设备规格 | 标称总带宽 | 单 FIFO 输入排队 实际可用(×58.6%) |
被结构吃掉的带宽 | 业务含义 |
|---|---|---|---|---|
| 48 × 25G + 6 × 100G | 1.8 Tbps | ≈ 1.05 Tbps | ≈ 0.75 Tbps | 虚拟化东西向流量在高峰期出现无法解释的重传 |
| 32 × 400G | 12.8 Tbps | ≈ 7.5 Tbps | ≈ 5.3 Tbps | 存储集群读写抖动,P99 时延失控 |
| 64 × 800G | 51.2 Tbps | ≈ 30.0 Tbps | ≈ 21.2 Tbps | AI 训练集群 All-Reduce 拖尾,GPU 大量时间在等网络而非算 |
| 关键洞察:损失比例是固定的 41.4%,与速率无关。这意味着你越是升级到高速端口,被浪费的绝对带宽就越惊人。 这就是为什么"提升端口速率"永远无法解决 HOL 阻塞——结构问题只能用结构手段解决。 | ||||
现在我们把整条推理链摆在一起,你会发现答案已经被逼到墙角,只剩一个出口:
图 3-3 VOQ 不是某个天才的灵光一闪,而是三次排除法之后剩下的唯一选项。
如果 HOL 阻塞的病根是"调度器一次只能看见一个包",那么最直接的治法是什么? ——让调度器同时看见"每一个出口方向上的第一个包"。
要做到这一点,我们必须把入口的一条队伍,按目的出口拆成 N 条独立的队伍。 请预测三件事:(1)这样一台 N 端口交换机总共需要多少条队列? (2)拆完之后,谁来决定"这一时隙从哪条队里取包"? (3)这个"谁",会不会变成新的瓶颈?
HOL 阻塞浪费的从来不是带宽,而是"把带宽用起来的机会";而机会的敌人,永远是被强行捆在一起的顺序。
—— 第三章金句第三章我们诊断出病根:调度器的视野被 FIFO 挡住了——它一次只能看见每个入口的第一个包。 那么,如果你是芯片架构师,你会怎样"把视野还给调度器"?
注意约束条件:你不能把缓冲搬到出口(第二章证明买不起),
所以包必须继续留在入口。
唯一还能动的东西是——包在入口里的"组织方式"。
请想一想:如果不按"到达顺序"排队,而按"要去哪里"排队,会发生什么?
答案朴素到近乎平庸:既然一条队只能露出一个包,那就多开几条队。 具体做法是——在每个入口,为每一个可能的出口,单独维护一条队列。
于是入口 1 不再是"一条队",而是变成 队列(1→A)、队列(1→B)、队列(1→C)…
共 N 条。一个新到的包不再"排到队尾",而是先查表确定目的出口,
再被投递到对应出口的那条专属队列里。
VOQ 没有多用一个字节的内存(实际实现中缓冲通常是共享的),也没有提高一点内存带宽(仍是 2×R)。
它改变的只有一件事:调度器每一时隙能"看见"的候选包,从 1 个变成了 N 个。
这是工程史上最优美的一类进步——不靠增加资源,而靠改变信息的可见性。
在管理学上这叫"把串行审批改成并行审批",在计算机体系结构上这叫"乱序执行",在这里它叫 VOQ。
一种交换机排队架构:数据包物理上缓存在入口,但入口的缓冲被按目的出口(及可选的服务等级 CoS) 划分为多条逻辑上相互独立的队列。每个入口维护 N 条 VOQ,全机共 N² 条(含 CoS 时为 N²×C 条)。
调度器在每个时隙从所有非空 VOQ 的队首中,计算一个入口与出口之间的匹配(Matching), 使尽可能多的入-出口对同时传输。
"虚拟"二字的含义:队列按出口来组织(逻辑归属出口), 但存储在入口(物理位于入口)——它"虚拟地"扮演了输出队列的角色, 故名 Virtual Output Queue。这是理解这个名字的唯一钥匙。
回到第三章那条绝望的超市队伍。VOQ 的做法不是"多开收银台"(那是增加资源,等于出口缓冲,买不起), 而是——在同一批顾客里,按"要去哪个出口"分成几条平行的队。
更贴切的类比是十字路口的转向车道:
❌ 没有转向道:一条车道混排,一辆等待左转的车(对面来车不断)会把后面所有直行车全部卡住 →
这就是 IQ + HOL;
✅ 有左转道/直行道/右转道:左转车老实待在左转道里等它的绿灯,直行车从直行道畅行无阻 →
这就是 VOQ。
关键点:路口的通行能力(出口带宽)一点没变,车道总宽度也没变; 变的只是"把不同去向的车分开摆放"。而通行效率因此提升了 40% 以上。
下面是本文最重要的一张图。请把它左右对照着看: 输入的流量完全相同,出口能力完全相同,唯一的差别是入口的队列组织方式。 然后看最下面一行的吞吐结果。
图 4-1 完全相同的流量与硬件,仅改变入口队列的组织方式,吞吐从 33% 变为 100%。 这就是"结构问题必须用结构手段解决"的最好证明。
这是最多人卡住的地方。让我用一张图把 VOQ 的"双重身份"彻底摊开: 它在物理世界属于入口,在逻辑世界属于出口。
图 4-2 蓝色虚线框(横向)是内存的物理所在;绿色实线框(纵向)是逻辑上"出口 B 的队列"。 同一批格子,两种读法——这就是"虚拟"的全部含义。
因为每条 VOQ 的写入方只有一个——它所在的那个入口端口。所以入口缓冲的访问需求依旧是 "1 次写(本端口收包)+ 1 次读(被调度取走)" = 2×R,与 N 完全无关。 这就是 VOQ 能扩展到 51.2 Tbps 而 OQ 不能的根本原因。
如果出口 A 严重拥塞,堆积的包会全部积压在各入口的 VOQ(*,A) 里,
而不会涌入交换网。交换网内部因此可以保持近乎无缓冲、无拥塞的状态。
类比:这好比高速公路入口匝道信号灯(Ramp Metering)—— 把车堵在匝道上,而不是让它们涌进主路造成全线瘫痪。 拥塞管理的第一原则永远是"在源头限流",而不是"在中间抢救"。
因为每条 VOQ 都能被单独计数、单独标记、单独限速,交换机得以实现:
这一点在 AI/存储网络中价值极高: 无损以太网(Lossless Ethernet)的最大难题是"拥塞扩散"与"受害者流(Victim Flow)"。 VOQ 提供的细粒度可见性,是实现精确拥塞控制的前提。看不见,就无法控制。
理论讲完,我们把镜头对准一个具体的包,看它从进入到离开经历了什么。 这五个阶段是所有现代 VOQ 交换机(包括 Cisco Nexus 系列)的通用流水线。
图 4-3 VOQ 交换机的通用五级流水线。第 2 步决定"进哪条队",第 4 步决定"何时能走"。
| 维度 | IQ(单 FIFO 输入排队) | OQ(纯输出排队) | VOQ(虚拟输出排队) |
|---|---|---|---|
| 队列总数 | N 条 | N 条(在出口) | N² 条(× CoS 级数) |
| 缓冲物理位置 | 入口 | 出口 | 入口(逻辑归出口) |
| 内存带宽需求 | 2 × R ✓ | (N+1) × R ✕ | 2 × R ✓ |
| HOL 阻塞 | 严重(结构性) | 无 | 在出口维度上消除 |
| 饱和吞吐上限 | 58.6% | 100% | 100%(依赖调度算法) |
| 调度器复杂度 | 极低(无需匹配) | 低(各出口独立) | 高(每时隙求二分图匹配) |
| 拥塞隔离能力 | 差(互相传染) | 好 | 优(可细到"出口×优先级") |
| 可扩展性(N 增大) | 可扩展但性能不可用 | 不可扩展 | 可扩展(代价在状态与调度) |
| 历史地位 | 1980s 早期方案,已淘汰 | 永恒的"性能标尺" | 1990s 至今的工业标准答案 |
这是专业读者最容易踩的坑,也是我坚持要写进白皮书的原因。准确的说法是: VOQ 消除的是"出口维度(Output-port dimension)上的 HOL 阻塞",而非所有 HOL 阻塞。
| 阻塞类型 | 现象 | VOQ 是否解决 |
|---|---|---|
| 出口维度 HOL | 去 A 口的包挡住去 B 口的包 | ✓ 完全解决——这正是 VOQ 的设计目标 |
| 优先级维度 HOL | 同去 A 口,低优先级的大包挡住高优先级的小包 | △ 需把 VOQ 再按 CoS 细分为 N²×C 条队列才解决 |
| 同队列内 HOL | 同去 A 口、同优先级,两条不同的 TCP 流互相拖累 | ✕ 无法解决——需更细粒度(如 per-flow 队列 / 动态队列分配) |
| 跨设备 HOL(PFC 引发) | 下游发 PFC 暂停帧,上游整个优先级组停发,波及无关流量(受害者流) | △ VOQ 提供可见性,但根治需 ECN/DCQCN 等端到端拥塞控制配合 |
第一性原理的普适规律:HOL 阻塞的严重程度,取决于"队列的划分维度"是否覆盖了"资源的竞争维度"。 资源在哪个维度上会独立忙闲,队列就必须在那个维度上独立存在。 VOQ 在"出口"这个最主要的维度上做了划分,所以收益最大; 而每往下多划一个维度(优先级、流),收益递减、成本递增——这就是所有队列设计的成本收益曲线。
第四问的答案:VOQ 是"在入口按目的出口分别排队"的架构。
它用 N² 条逻辑队列换来了 调度器的完整视野,
从而在保持 2×R 廉价内存带宽的同时,把吞吐上限从 58.6% 推回 100%。
但请回看 图 4-1 右侧那三条漂亮的绿色匹配线。它们是被"画"出来的—— 现实中,必须有人在 1.3 纳秒内把它们算出来。 而这个"算",是一个规模为 N×N 的二分图匹配问题。
现在你有 64 个入口、64 个出口、4096 条 VOQ,其中可能有上千条非空。 每个入口最多只能发 1 个包,每个出口最多只能收 1 个包。 请在约 1.3 纳秒内,给出一组"尽可能多、且长期公平"的配对方案。
这就是 VOQ 交换机每一个时隙都必须解决的问题。
请思考三个追问:(1)入口怎么告诉调度器"我有包要去 B"?
(2)当 3 个入口都想去 B,凭什么决定给谁?
(3)如果永远轮不到某个入口,会发生什么?
下一章我们用一个可交互的动画,把 Request / Grant / Accept 三次握手和 iSLIP 调度器彻底拆开。
VOQ 没有增加一个字节的内存,也没有加快一纳秒的时钟——它只是让调度器看见了本来就存在的机会。最好的架构创新,往往是信息的重组,而非资源的堆砌。
—— 第四章金句第四章我们给了调度器完整的视野,但也给了它一个新麻烦: 现在它面前摊着 4096 条队列,其中上千条有包等着走。 而规则是——每个入口这一时隙最多发 1 个包,每个出口最多收 1 个包。
请你在 1.3 纳秒内,从这上千种可能里挑出"尽可能多、且长期公平"的一组配对。
这道题在数学上有个名字。而"1.3 纳秒"这个约束,会让所有数学上的最优解全部失效。
工程师最后是怎么妥协的?
把问题抽象一下:左边 N 个入口,右边 N 个出口,
如果 VOQ(i,j) 非空,就在入口 i 与出口 j 之间画一条"可能的连线"。
调度器要做的事是:从这些可能的连线中,挑出一组互不冲突的线——
每个入口最多连一条,每个出口最多连一条。
在二分图(Bipartite Graph)中选出一组边,使任意两条边都不共享顶点。 在交换机语境下,一个匹配就是一组"入口→出口"的传输许可,保证无冲突。
舞池里 64 位男士(入口)与 64 位女士(出口)。每位男士手里有一张"意愿清单" (他有哪些 VOQ 非空),每位女士也只能接受一位舞伴。
理想主义:撮合出全场最和谐的配对(MWM)——但要算遍所有组合,
音乐早就放完了。
现实主义:让所有人同时喊出邀请,女士各自挑一个,
男士再从答应自己的女士中挑一个——三轮喊话搞定,虽不最优,但足够好。
这个"三轮喊话",就是 Request / Grant / Accept 三次握手。
它是整个 VOQ 工程化的灵魂:用"并行的局部决策"逼近"串行的全局最优"。
为什么需要三步而不是两步?这是个值得追问的细节。 如果只有"请求 + 授予"两步,会出现一个尴尬局面:3 个出口同时授予了同一个入口, 而这个入口只能接受一个——另外两个出口的授予就白白浪费了。 所以必须有第三步,让入口明确回复"我接受哪一个", 被拒绝的出口才知道自己这一时隙落空了(在多轮迭代中可以重新去找别人)。
图 5-1 RGA 三次握手。它的精髓是"分布式并行仲裁":没有任何一个中心节点需要看全局,每个端口只做本地决定。
三次握手只解决了"无冲突",还没解决"公平"。如果每个出口每次都偏爱入口 1, 那入口 4 可能永远发不出包——这叫饿死(Starvation)。 iSLIP(由 Nick McKeown 于 1999 年提出,被称为 iterative round-robin with SLIP) 用一个极简的办法解决了它:给每个出口和每个入口各配一个轮询指针。
VOQ(i,j) 非空的出口 j 发请求。g[j] = i+1、a[i] = j+1 向前推进。假设出口 A 授予了入口 1,但入口 1 转头接受了出口 B(拒绝了 A)。 如果 A 此时就把指针推走,那么入口 1 明明没被服务,却已经失去了优先权。 在特定流量模式下,这会导致某些入口被反复"授予但落空", 指针不断前进,它却永远拿不到实际带宽——饿死重现。
结果有多好?在均匀流量下,iSLIP 仅需 1 次迭代就能达到
100% 吞吐(因为指针去同步后,匹配几乎总是完美的)。
它的复杂度是 O(1) 的硬件轮询逻辑,可以做成纯组合电路——
这就是它击败理论最优的 MWM(O(N³))成为工业标准的原因:够好、够快、够公平。
想象食堂打饭:窗口叫了你的号,但你正在别的窗口打汤,没去。
宽厚的做法是——你的号继续保留在最前面,下次还先叫你。
这样谁都不会因为"运气不好错过一次"就被排到最后。
iSLIP 的公平性,本质上就是"只有真正吃到饭,才算你排过队"这条朴素原则。
现在把上面的一切合起来跑一遍。下面是一台 4 端口 VOQ 交换机, 共 16 条 VOQ,装载了 20 个包,且刻意设计成"大量流量涌向出口 A"的 Incast 模式。 右侧是一台使用完全相同流量的 IQ 交换机作为对照组。
请点击「下一步」逐阶段观察 Request → Grant → Accept, 并留意红色指针如何移动,以及底部两条进度条如何越拉越开。
VOQ 矩阵(格内数字 = 该队列中待发包数)
累计吞吐率:— 已送 0/20
累计吞吐率:— 已送 0/20
上面的 iSLIP 假设有一个中央调度器能在一个时隙内和所有端口通信。 在一台单芯片交换机里这没问题;但在一台机框式设备(多块线卡 + 多块交换网板)里, 线卡到中央调度器的往返延迟可能就有几微秒——比一个包时隙长几千倍。 于是现代高端平台(包括 Cisco Nexus / 8000 系列)普遍采用基于信用的分布式 VOQ。
出口(或代表出口的调度实体)向各入口预先发放"信用(Credit)"。 一份信用代表"你被允许向我发送一个数据单元的额度"。 入口只有持有信用才能发送,发送后信用被消耗;出口按自身实际排空能力持续补发信用。
它把"每时隙的集中仲裁",转化为持续的、流水线化的额度分配—— 因此可以容忍芯片间的往返延迟。
中央调度(iSLIP)像举手叫服务员:你举手,服务员看一眼全场, 决定先去谁那儿。全场很大时,他跑不过来。
信用机制像取号排队:餐厅(出口)根据翻台速度提前发号, 你拿到号就知道自己能进;没号就在门外等(包留在 VOQ 里)。 服务员不需要每秒扫视全场,系统自然平衡。
而且——发多少号,餐厅自己最清楚。这就是为什么信用由出口发放: 只有出口知道自己真实的排空速度。
图 5-2 信用机制把"每时隙的全局仲裁"变成"持续的额度流水线",使 VOQ 得以跨越多芯片、多机框扩展。
| 算法 | 复杂度 | 吞吐性能 | 核心思想 | 工程评价 |
|---|---|---|---|---|
| MWM 最大权重匹配 |
O(N³) | 100% 且稳定 |
以队列长度或等待时间为权重,求全局最优匹配 | 理论金标准,但 N=64 时需数万次运算,硬件无法在纳秒内完成 |
| MSM 最大规模匹配 |
O(N2.5) | <100% 可能不稳定 |
只求"配对数量最多",不看队列长度 | 会饿死轻载队列;在非均匀流量下可能失稳,不可用 |
| PIM 并行迭代匹配 |
O(log N) 轮 | 约 63%(单轮) | 出口在请求者中随机选一个 | 需硬件随机数发生器,成本高且不公平;iSLIP 的前身 |
| iSLIP 迭代轮询 |
O(1) 硬件 × log N 轮 |
100% (均匀流量,1 轮即可) |
轮询指针 + 三次握手,指针仅在 Accept 后推进 | 工业标准答案。无饿死、可纯组合电路实现、指针自动去同步 |
| Credit-based 信用驱动 |
分布式 O(1) |
接近 100% | 出口按真实排空能力预发额度,入口凭额度发送 | 大规模平台首选。可容忍芯片间 RTT,天然支持 QoS 加权与多机框扩展 |
| Cell Spraying 信元喷洒 |
O(1) | ≈100% 负载完美均衡 |
把包切成定长信元,均匀喷洒到所有 fabric 链路,出口重组 | 常与 VOQ 配合。彻底消除 fabric 内部热点,代价是需在出口做重排序(Reorder) |
第五问的答案:由调度器通过Request / Grant / Accept 三次握手决定, 并用iSLIP 的轮询指针保证公平与无饿死;在跨芯片的大规模平台上, 则演化为基于信用的分布式调度。这一切的目标只有一个: 在 1.3 纳秒内做出一个"足够好"的决定。
到这里,VOQ 看起来近乎完美:省内存带宽、100% 吞吐、公平、可扩展、拥塞隔离。 但一个成熟的架构师此刻应该警惕——因为在工程世界里, 没有任何权衡会凭空消失,它只会换个地方出现。
请回头数三笔账:(1)N=64、8 级 CoS 时,共需 32,768 条队列—— 每条队列的指针、计数器、链表头尾都要占芯片面积,这笔状态开销去哪儿了? (2)一个包从入队到获准,至少要经历一次"请求—授予"的往返, 这笔固定延迟是多少?空载时也躲不掉吗? (3)入口缓冲越深,能吸收的突发越大——但一个包在队列里排 5 毫秒才发出, 对 TCP 意味着什么?
换句话说:VOQ 用什么换来了它的 100%?下一章我们诚实地把账单摊开。
iSLIP 的伟大不在于它算得最好,而在于它承认"算不完"——于是改用并行的局部决策,逼近全局最优。工程的智慧,往往始于放弃对完美的执念。
—— 第五章金句如果一项技术只有优点,它一定不是技术,而是营销。
请你先自问一个问题:既然 VOQ 从 1990 年代就被证明是最优解,
为什么直到今天,工程师们还在为"缓冲要多深"、"要不要 PFC"、"深缓冲还是浅缓冲"吵得不可开交?
答案是:VOQ 解决了"HOL 阻塞"这个问题,但它自己带来了三个新问题——
而这三个新问题,恰好是今天数据中心网络所有争论的技术原点。
我们逐笔算清楚:面积账、时间账、缓冲账。
在批判之前先公正地肯定。VOQ 的优势不是"性能好"这么笼统,它是五个可分别验证的具体收益:
消除出口维度的 HOL 阻塞。同一批硬件,可用带宽提升约 70%(100 ÷ 58.6 ≈ 1.71)。 这是最直接、最容易被量化的收益,也是采购决策中最硬的数字。
每条 VOQ 只有一个写入方,与端口数 N 完全解耦。这是 VOQ 能支撑 51.2 Tbps 甚至 102.4 Tbps 单芯片的根本原因——而 OQ 在 N 增大时直接撞墙。
拥塞流量堆积在入口 VOQ,不进入交换网。交换网因此可保持近乎无缓冲、 无拥塞状态,避免"一个热点污染全机"的连锁反应。这是无损网络的前提。
每条 VOQ 可单独计数、单独标记 ECN、单独限速。得以实现"只惩罚肇事流、不连坐无辜流"。 看不见就无法控制——VOQ 提供了控制所需的最小粒度。
配合 iSLIP/信用机制,可给出延迟上界与无饿死保证。 对金融交易、工业控制、AI 训练同步等场景,"可预测"往往比"更快"更值钱。
OQ 的思路是用空间(N 倍内存带宽)解决冲突;VOQ 的思路是 用时间(每时隙做一次调度决策)解决冲突。而时间比空间便宜—— 这就是 VOQ 胜出的第一性原理。
优势 2 说"内存带宽不随 N 增长",这是真的。但队列的"数量"却随 N 平方增长。 而每一条队列,都不是免费的概念——它在硅片上是一堆实实在在的电路。
每条队列至少需要维护:
物流中心把货物按目的城市分区堆放(这是好事,避免堵门)。但每一个分区都需要 一块牌子、一个库管、一本进出账、一套报警阈值。
目的城市从 4 个涨到 64 个,分区数量从 16 涨到 4096——货物总量一点没变, 但"管理开销"涨了 256 倍。
这就是 N² 的真实含义:不是内存变大了,是"账本"变多了。 而在芯片上,账本要用最贵的高速寄存器实现。
图 6-1 N² 曲线是 VOQ 最真实的成本。它不吃内存带宽,但吃芯片面积、吃功耗、吃调度器的收敛时间。
洞察:在任何时刻,绝大多数 VOQ 是空的。一个入口通常只在与少数几个出口通信。 所以不必为 4096 条队列都预分配硬件资源,而是维护一个较小的队列资源池, 按需绑定到"活跃的(入口, 出口, CoS)"组合上,空闲后回收。
类比:酒店不给每位可能的客人都留一间房,而是入住时分配、退房后回收。 代价是需要一套"前台系统"(映射表 + 哈希/CAM 查找),且极端情况下会房源不足—— 此时多条流被迫共享一条队列,局部 HOL 阻塞回归。
不按"每个出口端口"建队列,而是按"目的线卡 / 目的芯片"建第一级队列, 再在目的侧做第二级细分。若一台设备有 16 块线卡、每卡 32 口, 队列数从 512² 降到 16 × 16 的粗粒度 + 卡内细分,数量级骤降。
代价:同一线卡上不同端口的流量共享一条队列 → 线卡内部可能出现 HOL。 这是典型的"粒度 vs 成本"权衡。
不必为所有 8 个 CoS 都建满 N² 队列。常见做法是:高优先级/无损队列做全 VOQ 细分, 而 Best-Effort 流量共享较粗的队列。把有限的精度花在最需要保护的流量上。
N² 条队列共享同一块物理缓冲池,队列只是链表结构(指针 + 计数), 不预留独占内存。这样内存利用率极高,代价是需要一套复杂的 动态阈值算法(Dynamic Threshold)防止某条队列吃光全部缓冲。
请记住这条普适规律:所有对抗 N² 的手段,本质都是
"用部分 HOL 阻塞的回归,换取硬件成本的下降"。
这就是为什么不同厂商、不同定位的产品,会给出完全不同的答案——
没有绝对正确的粒度,只有匹配业务的粒度。
这是最容易被忽略、却最影响低延迟场景的代价。 在纯 OQ 架构中,包"到了就送到出口";而在 VOQ 架构中,包必须先请求、等授予、再穿越。 这意味着即使整台交换机空载无拥塞,每个包也要付一笔固定的"调度税"。
图 6-2 VOQ 的"调度税"在拥塞时可忽略(因为排队延迟远大于它), 但在空载低延迟场景下,它是纯粹的净损失。
这就是架构选择的第一性原理: 永远先问"我的流量长什么样",再问"我该选什么架构"。 脱离流量模型谈架构优劣,是所有网络设计错误的头号来源。
这是当今数据中心网络最激烈的争论,而它的技术原点正是 VOQ。 逻辑链条是这样的:VOQ 把拥塞流量堆在入口 → 堆得越多需要缓冲越深 → 缓冲越深,包在队列里待的时间越长 → 端到端延迟暴涨。
由于设备配置了过大的缓冲区,拥塞时数据包在队列中积压极长时间而不被丢弃, 导致端到端延迟大幅上升的现象。
为什么这是坏事?因为 TCP 是靠丢包或 ECN 标记来感知拥塞的。 缓冲太深 = 拥塞信号被延迟传递 = 发送端在很长时间里误以为一切正常并继续加速 = 最终一次性大规模丢包 + 剧烈震荡。
核心矛盾:缓冲的作用是"吸收突发",但过深的缓冲会"掩盖过载"。
一家餐厅门口只放 10 张等候椅:满了就明确告知"客满,请改天"(丢包 = 清晰的拥塞信号), 顾客立刻转去别家,全城效率最优。
另一家餐厅摆了 500 张椅子:所有人都能坐下——但要等 3 小时。 更糟的是,因为"有位子",后面的人还在源源不断地加入。 没人被拒绝,但所有人的体验都灾难性地变差了。
这就是 Bufferbloat:用"不丢包"换来了"极高延迟",而后者往往更致命。
| 维度 | 深缓冲阵营(Deep Buffer) | 浅缓冲阵营(Shallow Buffer) |
|---|---|---|
| 核心主张 | 宁可延迟,也不要丢包。丢包引发的重传与超时代价,远高于排队延迟。 | 宁可早丢/早标记,也不要掩盖拥塞。让端侧尽快降速才是全局最优。 |
| 典型缓冲量 | 数百 MB ~ GB 级(常配外挂 HBM) | 数十 MB 片上 SRAM |
| 擅长场景 | 大象流为主、长距 WAN/DCI、高扇入 Incast、跨地域备份,链路 BDP 极大 | 短 RTT 的机架内/集群内、以 ECN/DCQCN 精确控速的 RDMA、低延迟交易 |
| 对 TCP 的影响 | 易造成 RTT 膨胀与拥塞窗口误判,加剧震荡 | 拥塞信号及时,控速环路稳定 |
| 成本与功耗 | 高(外挂内存 + 更多 SerDes + 更大功耗) | 低(全片上) |
| 失效模式 | Bufferbloat:P99 延迟失控,AI 训练出现长尾拖尾 | 微突发丢包:短突发被丢,触发重传,有效吞吐下降 |
| 成熟结论 | 这不是"谁对谁错",而是"BDP 匹配问题"。
缓冲的合理量级应当接近 链路带宽 × 往返延迟(BDP):
机架内 RTT 极小 → 浅缓冲足够;跨地域 RTT 大 → 必须深缓冲。真正的解法是"适量缓冲 + 主动队列管理(AQM)+ 端到端拥塞控制"三者协同—— 让 VOQ 提供可见性,让 ECN/AQM 及时发信号,让端侧真正降速。 |
|
为了让交换网负载均衡,现代实现常把包切成定长信元(Cell)并 喷洒(Spraying)到多条 fabric 链路。不同链路延迟不同, 信元会乱序到达。
因此出口必须有重排序缓冲(Reorder Buffer)+ 序列号机制。 这带来额外的芯片资源、额外的固定延迟,且重排序缓冲一旦不足会直接丢包—— 这是机框式设备最隐蔽的性能悬崖之一。
调度器是全机最复杂、时序最紧的电路。它必须在一个包时隙内完成多轮仲裁, 任何时序余量不足都会直接限制芯片主频与端口密度。
在机框式设备中,调度还依赖带内/带外控制通道。 控制通道的抖动或丢失会导致信用泄漏(Credit Leak)—— 表现为"链路明明空闲、流量却上不去",是现场排障中极难定位的一类故障。
iSLIP 的"100% 吞吐"结论建立在均匀随机流量假设上。 真实流量高度非均匀(少数大象流 + 大量老鼠流 + 强 Incast)。
在极端非均匀模式下,单轮 iSLIP 可能达不到 100%,需要更多迭代轮次或 加权/优先级增强的调度策略。这也是为什么厂商实现会在标准 iSLIP 上做大量私有优化—— 论文给出的是下限保证,产品竞争的是非理想场景下的表现。
数千条队列意味着数千组计数器与阈值。这带来两个现实问题:
| 项目 | 具体内容 | 量级 / 影响 | 缓解手段 |
|---|---|---|---|
| 收益 | 消除出口维度 HOL | 吞吐 58.6% → 100% (可用带宽 +71%) |
— |
| 内存带宽与 N 解耦 | 始终 2×R,可扩展至 100 Tbps+ | — | |
| 源头拥塞隔离 + 细粒度可见性 | 交换网无拥塞;支持精确 ECN/PFC/QoS | — | |
| 代价 | N² 状态爆炸 | 64 口 × 8 CoS = 32,768 条队列 | 动态队列分配、分层 VOQ、共享缓冲池 |
| 固定调度延迟(调度税) | 单芯片数十~数百 ns;跨卡可达 μs 级 | 直通转发优化、信用预授予、空载旁路 | |
| 缓冲膨胀风险 | 深队列导致 P99 延迟失控 | 按 BDP 定容、AQM/WRED、ECN + DCQCN | |
| 乱序重排 + 调度器复杂度 + 运维负担 | 额外芯片资源、隐性故障模式、遥测压力 | 信元序列号、健壮信用协议、亚毫秒遥测 | |
| 净判决 | 在存在任何显著拥塞与 Incast 的场景下,VOQ 的收益远大于代价—— 这就是它成为工业标准的原因。但它不是免费的,也不是万能的: 它把"排队问题"转化为"调度与缓冲管理问题",而后者需要架构师主动设计,而非默认正确。 | ||
第六问的答案:VOQ 用三笔账换来了它的 100%—— 面积账(N² 状态膨胀)、时间账(固定调度延迟)、 缓冲账(深缓冲带来的延迟与膨胀风险)。 再加上乱序重排、调度器复杂度与运维负担。
而这恰恰解释了本章开头那个疑问:为什么工程师们至今还在争论? 因为VOQ 只是提供了"能力",它并不自动提供"正确的配置"。 能力如何被恰当地使用——缓冲配多深、ECN 门限设多少、哪些流量走无损队列—— 这才是从原理走向落地的最后一公里。
现在你已经完整掌握了 VOQ 的原理、优势与代价。最后一个问题是最实际的: 当你面对一份真实的产品规格书、或者一个真实的 AI 训练集群设计时, 你该看哪些指标、问哪些问题、避开哪些坑?
下一章我们回到工程现场:Cisco 是如何把 VOQ 落地的—— 从 Crossbar 与集中调度,到 CloudScale ASIC 的分布式 VOQ 与共享缓冲; 以及在 AI/ML 数据中心里,VOQ 如何与 PFC、ECN、DCQCN 协同, 构成真正可用的无损以太网。
任何声称"没有代价"的架构,都只是还没有被推到极限。VOQ 的伟大不在于它免费,而在于它把账单换成了一种我们付得起的货币——时间与逻辑,而非空间与物理。
—— 第六章金句前六章我们推导出了 VOQ 的原理。但原理不会自动变成一台能跑 AI 训练的交换机。 请想一想:一台真实的设备,要把 VOQ 从纸面变成硅片,还必须回答哪些"不优雅但致命"的问题?
至少有四个:(1)调度器放哪里——单芯片内还是跨机框?
(2)缓冲怎么分——每条队列独占还是全局共享?
(3)VOQ 只管交换机内部,那交换机之间的拥塞谁管?
(4)我作为架构师,看规格书时该看哪几个数字?
这一章我们逐个回答,并给出一份可以直接带去项目现场的检查清单。
VOQ 的工程实现经历了一次清晰的代际演进,理解这个演进过程,你就能看懂 为什么固定盒式(Fixed)与机框式(Modular)设备的行为差异如此之大。
图 7-1 两代实现的分水岭是"调度决策的位置":从"集中的一次性仲裁"演进为"分布式的持续额度分配"。
以 Nexus 9300 系列所采用的 CloudScale ASIC 家族为代表。 其架构特征通常包括:
以 Nexus 9500 系列为代表。入口线卡为全机所有出口维护 VOQ, 数据被切成信元后喷洒到多块 Fabric Module,出口线卡负责重组与整形。 调度由信用机制驱动,而非集中式 iSLIP。
Cisco 8000 系列所采用的 Silicon One 架构,同样以 VOQ 为基础, 但面向长距、大 BDP 场景,通常提供更深的缓冲(含外挂高带宽内存), 以及可扩展到分布式机架系统(Distributed System)的 fabric 能力。
架构师的提醒:不要把"深缓冲"当作产品优劣的标签。 回到第六章的结论——缓冲应当匹配 BDP。 机架内 RTT 只有几微秒的 AI 集群,与跨大洲 RTT 上百毫秒的骨干链路, 需要的缓冲量差了三个数量级。用错了方向,深缓冲就变成 Bufferbloat。
这是从原理走向落地时最关键的一次认知升级。请务必牢记: VOQ 是"设备内部(Intra-switch)"的机制。 它完美地解决了"一台交换机内部,入口到出口"的调度问题, 但它对"交换机之间"、"服务器到服务器"的端到端拥塞无能为力。
结论:VOQ 提供的是"可见性 + 隔离性"。
如果一台 GPU 服务器持续以 400G 向一个只能吃 100G 的目标发送, VOQ 只能忠实地把队列堆到满,然后开始丢包。
它无法"通知"那台服务器降速——因为降速的权力在端侧的协议栈/网卡手里。 要根治过载,必须有端到端的拥塞控制。
在 AI 训练与 RDMA 存储网络中,VOQ 从不单独工作。它与 PFC(逐跳的"急刹车") 和 ECN/DCQCN(端到端的"油门微调")组成一套完整的拥塞管理体系。 理解三者的分工,是设计无损网络的核心能力。
图 7-2 三层防线的时间尺度差了六个数量级。VOQ 管纳秒、PFC 管微秒、ECN 管毫秒——各司其职,缺一不可。
| 机制 | 作用范围 / 时间尺度 | 它做什么 | 精妙类比 | 失效模式与注意点 |
|---|---|---|---|---|
| VOQ | 设备内部 纳秒级 |
按出口分队排队、消除 HOL、吸收微突发、提供细粒度拥塞可见性 | 路口的转向专用道:不同去向分开摆放,互不阻塞 | 只能"容纳"拥塞,不能"消除"过载。队列满了照样丢包。 需正确配置动态阈值,防单队列吃光缓冲 |
| PFC | 逐跳(相邻两跳) 微秒级 |
按优先级向上游发 Pause 帧,暂停该优先级的发送,实现零丢包 | 急刹车:立刻止血,但车上的人会被甩一下 | 拥塞扩散(Congestion Spreading)、受害者流(Victim Flow)、
极端情况下 PFC 死锁。 务必只对必要的优先级启用,并配好 Watchdog |
| ECN / DCQCN | 端到端 毫秒级 |
标记拥塞 → 接收端回通告 → 发送端网卡按算法平滑降速 | 油门微调:提前松油门,车上的人毫无感觉 | 门限(Kmin/Kmax)设置过高则反应太迟、过低则吞吐损失。 必须与 RNIC 侧算法参数协同调优,两端不匹配则整体失效 |
| 核心设计口诀:VOQ 打地基,ECN 做主力,PFC 当保险。 三者的触发阈值应形成阶梯:ECN 门限 < PFC 门限 < 队列上限。 这样系统总是先温和降速,其次才急刹车,最后才丢包。阈值顺序配反,是无损网络翻车的头号原因。 | ||||
这是本章最实用的部分。以下清单可以直接带去评审会—— 每一条都能追溯到前六章的某个第一性原理。
| # | 应当问的问题 | 为什么要问(对应原理) | 健康的答案长什么样 |
|---|---|---|---|
| 1 | 该平台是VOQ 架构还是单队列输入排队? | 第三章:单 FIFO 吞吐上限仅 58.6% | 明确说明入口按目的(端口/线卡)分队;能给出 HOL 消除机制说明 |
| 2 | VOQ 的粒度是"每出口端口"还是"每出口线卡"?是否细分 CoS? | 第四章表 4-2:粒度决定 HOL 消除的彻底程度 | per-port + per-CoS 为佳;若为 per-linecard,需评估卡内 HOL 风险 |
| 3 | 队列是静态预分配还是动态按需分配?资源池耗尽时如何降级? | 第六章 6.2:N² 状态爆炸的缓解手段 | 动态分配 + 明确的耗尽降级行为(而非"未定义") |
| 4 | 缓冲是共享动态池还是每队列静态划分?动态阈值算法是什么? | 第一章 1.2:微突发吸收能力取决于可借用的缓冲量 | 共享池 + 动态阈值;单端口突发时可借用远超平均份额的缓冲 |
| 5 | 缓冲总量是多少?与我的 BDP 匹配吗? | 第六章 6.4:缓冲应匹配 BDP,而非越大越好 | 能算出"带宽 × RTT"并对比;而不是简单宣称"缓冲更大更好" |
| 6 | 空载状态下的端到端转发延迟是多少?调度开销占多少? | 第六章 6.3:调度税在低延迟场景是净损失 | 给出明确的空载延迟数据,并区分固定开销与排队延迟 |
| 7 | 调度是集中 iSLIP 还是分布式信用?跨线卡时如何工作? | 第七章 7.1:集中调度无法跨越芯片 RTT | 机框式平台必须是信用驱动;能说明信用回补与保护机制 |
| 8 | 是否使用信元喷洒?出口重排序缓冲的容量与溢出行为? | 第六章代价 4:重排序缓冲不足会直接丢包 | 明确说明重排序能力与超限行为,而非避而不谈 |
| 9 | 调度器在非均匀流量 / 强 Incast 下的实测吞吐是多少? | 第六章代价 6:100% 吞吐是均匀流量下的结论 | 有 Incast(如 32:1、64:1)实测数据,而非只给理论线速 |
| 10 | ECN 门限与 PFC 门限的推荐值?两者是否形成阶梯? | 第七章表 7-1:阈值顺序配反是翻车主因 | ECN 门限明显低于 PFC 门限;有针对具体流量模型的推荐配置 |
| 11 | 是否支持亚毫秒级缓冲遥测?能否记录队列峰值与微突发? | 第六章代价 7:微突发用秒级 SNMP 根本看不见 | 支持硬件峰值记录与高频采样导出,可定位微突发时刻与源端口 |
| 12 | PFC 是否有死锁检测 / Watchdog?受害者流如何缓解? | 第七章表 7-1:PFC 死锁会导致大面积业务中断 | 具备 PFC Watchdog 并可自动恢复;有明确的拥塞隔离设计 |
理论的最终检验是排障。以下三个 Case 按"故障现象 → 业务影响 → 故障根因 → 解决方案"整理, 每一个的根因都能回溯到本文的某一章。
带宽 × RTT 重新定容,为机架内短 RTT 流量设置合理的队列上限,
而非把可用缓冲全部开放;第七问的答案:Cisco(以及整个行业)把 VOQ 落地的路径,是 从集中调度走向分布式信用、从静态划分走向共享动态缓冲、 并把 VOQ 与 PFC / ECN 组成三层拥塞防线。 而作为架构师,你真正需要掌握的不是型号参数,而是那 12 个问题背后的第一性原理—— 因为参数会过时,原理不会。
VOQ 决定了一台设备的能力上限,而配置决定了你能兑现多少。买到的是硬件,用出来的才是架构。
—— 第七章金句
本文开篇问了一个问题:交换机为什么要给每一个出口开一条专属车道?
走完七级台阶,答案已不再是一个需要背诵的结论,而是一条你亲手推导出来的必然链条:
| 台阶 | 我们问了什么 | 物理与数学给出的回答 |
|---|---|---|
| 1 | 为什么一定要排队? | 因为"出口速率有限 + 流量突发 + 多入口竞争"三条物理事实,必然导致想出去的量 > 能出去的量。拥塞是算术,不是故障。 |
| 2 | 那把队列放在出口? | 逻辑最优,但需要 (N+1)×R 的内存带宽——被 SRAM 访问时间这堵物理硬墙挡死。 |
| 3 | 那放在入口? | 内存只需 2×R,但一条 FIFO 挡住了调度器的视野,吞吐被队头阻塞锁死在 2−√2 ≈ 58.6%。 |
| 4 | 还有别的选择吗? | 没有。只剩一条路:包留在入口(省内存),但按目的出口分成 N 条队(还视野)——这就是 VOQ。 |
| 5 | 它怎么跑起来? | Request / Grant / Accept 三次握手 + iSLIP 轮询指针;大规模平台则演化为信用驱动的分布式调度。 |
| 6 | 代价是什么? | 三笔账:N² 状态膨胀、固定调度延迟、深缓冲带来的膨胀风险。没有免费午餐,只有换过币种的账单。 |
| 7 | 怎么落地? | VOQ 打地基、ECN 做主力、PFC 当保险;缓冲按 BDP 定容,用遥测看见微突发。 |
如果只带走一句话,请带走这一句:
VOQ 没有增加一个字节的内存、也没有加快一纳秒的时钟。它只是改变了信息的组织方式,
让调度器看见了本来就存在的机会。
这也是我做了二十年架构后最深的体会:大多数系统的性能瓶颈,不在资源不足,而在结构错配。
在你的网络里、你的代码里、甚至你的组织流程里,
都可能正上演着一场"队头阻塞"——有人在等,有资源在闲。
而解法从来只有一个:把被强行捆在一起的顺序,拆开。
按主题分组,每一条都给出精准定义 + 一句类比或要点,并标注所属章节,便于回溯。
| 术语 | 精准定义 | 类比 / 要点 | 章节 |
|---|---|---|---|
| Buffer 缓冲区 |
交换机内部用于临时存放数据包的高速存储器(片上 SRAM 或外挂 HBM/DRAM)。 | 机场候机厅:给早到的人一个待着的地方,而非赶出机场 | 1.2 |
| Queue 队列 |
加在缓冲区上的服务顺序规则,通常为 FIFO,决定谁先被发送。 | 登机广播顺序。缓冲是空间,队列是秩序 | 1.2 |
| Burst / Microburst 突发 / 微突发 |
在极短时间窗口(微秒级)内集中到达的大量数据,瞬时速率可远高于平均速率。 | 五分钟均值 30% 完全可能掩盖 1 μs 的 300% 过载 | 1.1 |
| Contention 竞争 / 争用 |
多个数据流在同一时刻请求同一个不可共享的资源(如某出口端口)。 | 交换机作为"多对多汇聚点"的固有代价 | 1.1 |
| Statistical Multiplexing 统计复用 |
基于"各端口不会同时满速"的统计假设,用低于总接入带宽的上行容量承载流量。 | 队列是这场赌局的安全气囊 | 1.3 |
| OQ 输出排队 |
包立即被送至目的出口缓冲,所有排队与调度只在出口发生的模型。 | 每个登机口自建候机厅;性能金标准但需 (N+1)×R 内存带宽 | 2.1 |
| IQ 输入排队 |
每个入口维护单条 FIFO 队列的模型,内存带宽仅需 2×R。 | 便宜,但吞吐被 HOL 锁死在 58.6% | 2.3 |
| CIOQ 组合输入输出排队 |
入口与出口均有缓冲,且交换网内部具备加速比的混合架构。 | 加速比 S=2 即可精确模拟 OQ(Chuang et al., 1999) | 2.4 |
| Speedup 加速比 |
交换网内部运行速率相对端口线速的倍数。 | 把"不可能问题"变成"可控成本问题"的关键常数 | 2.4 |
| Crossbar 交叉开关 |
无缓冲的 N×N 交换矩阵,每时隙每出口只能接收一个输入。 | 正因"每出口每时隙只收一个",才需要调度器 | 2.3 |
| 术语 | 精准定义 | 类比 / 要点 | 章节 |
|---|---|---|---|
| HOL Blocking 队头阻塞 |
FIFO 队列中队首元素因资源不可用而无法被服务时,其后所有元素(即使资源空闲)被迫一同等待。 | 超市收银队里前面的大爷在理论优惠券。判据:资源空闲 + 请求等待 | 3.1 |
| 2 − √2 ≈ 58.6% | N→∞、均匀随机流量下,单 FIFO 输入排队交换机的饱和吞吐上限(Karol et al., 1987)。 | 数学定理,非工艺缺陷。12.8T 设备实际只能用出 7.5T | 3.4 |
| M/D/1 | 排队论模型:泊松到达(M)、确定性服务时间(D)、单服务台(1)。等待时间 W = ρ / (2(1−ρ))。 | 推导 58.6% 的数学工具 | 3.4 |
| VOQ 虚拟输出队列 |
包物理缓存于入口,但入口缓冲按目的出口(及可选 CoS)划分为多条逻辑独立队列的架构。 | 路口的转向专用道。"虚拟"= 逻辑归出口、物理在入口 | 4.2 |
| N² 队列规模 |
N 端口交换机的 VOQ 总数为 N×N;若细分 C 级 CoS 则为 N²×C。 | 64 口 × 8 CoS = 32,768 条。这是 VOQ 的主要成本 | 6.2 |
| Incast 多打一 |
多个发送端在同一时刻向同一接收端发送数据的流量模式。 | AI 集合通信、分布式存储、MapReduce 的常态而非例外 | 2.2 |
| Dynamic VOQ Allocation 动态队列分配 |
不为全部 N² 组合预分配硬件资源,而是从池中按需绑定活跃组合、空闲回收。 | 酒店入住时分配房间。代价:房源不足时局部 HOL 回归 | 6.2 |
| Hierarchical VOQ 分层 VOQ |
先按目的线卡/芯片建粗粒度队列,再在目的侧细分,以降低队列总数。 | 用"卡内可能的 HOL"换取硬件成本下降 | 6.2 |
| 术语 | 精准定义 | 类比 / 要点 | 章节 |
|---|---|---|---|
| Matching (二分图)匹配 |
在二分图中选出一组互不共享顶点的边;此处即一组无冲突的"入口→出口"传输许可。 | 一场必须在 1.3 ns 内结束的配对舞会 | 5.1 |
| MWM 最大权重匹配 |
以队列长度或等待时间为权重求最优匹配,可保证 100% 吞吐且稳定,复杂度约 O(N³)。 | 理论金标准,硬件无法在纳秒内完成 | 5.6 |
| RGA 三次握手 |
Request(入口请求)→ Grant(出口授予)→ Accept(入口接受)的分布式仲裁流程。 | 第三步不可省:否则多个出口授予同一入口会白白落空 | 5.2 |
| iSLIP | 基于轮询指针的迭代匹配算法(McKeown, 1999)。指针仅在 Accept 成功后推进。 | 食堂"只有真吃到饭才算排过队"。无饿死 + 指针自动去同步 | 5.3 |
| Starvation 饿死 |
某队列长期无法获得服务,延迟无界增长。 | 所有调度器必须首先排除的失效模式 | 5.3 |
| Desynchronization 指针去同步 |
iSLIP 中各出口指针自发互相错开,使授予天然指向不同入口的性质。 | 均匀流量下仅需 1 轮迭代即可达 100% 吞吐的原因 | 5.3 |
| Credit 信用 / 额度 |
出口预先向入口发放的发送额度;入口须持有信用才能发送,出口按排空能力持续补发。 | 餐厅号码牌,而非举手叫服务员。可容忍芯片间 RTT | 5.5 |
| Cell Spraying 信元喷洒 |
将包切为定长信元并均匀分发到所有 fabric 链路,出口重组。 | 消除 fabric 内部热点,代价是需出口重排序 | 5.6 |
| Reorder Buffer 重排序缓冲 |
出口侧用于将乱序到达的信元按序列号恢复原序的缓冲。 | 容量不足会直接丢包——机框式设备的隐性性能悬崖 | 6.5 |
| 术语 | 精准定义 | 类比 / 要点 | 章节 |
|---|---|---|---|
| Bufferbloat 缓冲膨胀 |
缓冲过大导致拥塞时包长期积压而不被丢弃,端到端延迟大幅上升的现象。 | 摆了 500 张椅子的餐厅:没人被拒绝,但要等 3 小时 | 6.4 |
| BDP 带宽时延积 |
链路带宽 × 往返时延,代表"在途数据量",是缓冲定容的合理基准。 | 缓冲既不是越大越好,也不是越小越好,而是要匹配 BDP | 6.4 |
| AQM / WRED 主动队列管理 |
在队列填满前按概率提前丢弃或标记包,以尽早传递拥塞信号。 | 对抗 Bufferbloat 的核心手段 | 6.4 |
| PFC 基于优先级的流控 |
按优先级向上游发送 Pause 帧,暂停该优先级发送以实现零丢包,作用于相邻两跳、微秒级。 | 急刹车。风险:拥塞扩散、受害者流、死锁。应作为"最后的保险" | 7.3 |
| ECN 显式拥塞通知 |
交换机在包头标记拥塞而非丢包,由接收端反馈给发送端降速,作用于端到端、毫秒级。 | 油门微调。门限须明显低于 PFC 门限 | 7.3 |
| DCQCN | 数据中心 RoCEv2 场景常用的拥塞控制算法,结合 ECN 标记与 RNIC 侧速率调整。 | 必须与网络侧门限协同调优,两端各自为政则整体失效 | 7.3 |
| Victim Flow 受害者流 |
因 PFC 按优先级暂停整条链路,而被无辜波及的无关流量。 | 单点异常升级为机架级事件的放大器 | 7.5 |
| CoS 服务等级 |
流量的优先级分类;VOQ 可按 (出口 × CoS) 细分以消除优先级维度的 HOL。 | 每多划一个维度,收益递减、成本递增 | 4.7 |
| Goodput 有效吞吐 |
扣除重传与协议开销后,真正交付给应用的有效数据速率。 | 评估无损网络应看 Goodput + P99 延迟,而非仅看丢包数 | 7.5 |
| SerDes | 串行器/解串器,负责并行数据与线缆高速串行信号的转换,其时钟决定端口速率上限。 | "出口速率刚性"这一物理事实的硬件根源 | 1.1 |
术语不是门槛,是共识的坐标。当我们对每个词的理解精确到同一位小数,复杂的架构讨论才可能真正开始。
—— 术语表结语