ifb 的机制是什么,为什么能比 drop 方案减少重传 ?
- 重定向: 哈哈哈,凡是不能直接解决的问题,都可以重定向解决
- 它重定向到了一个虚拟网卡,然后借助了虚拟网卡的 egress 的 队列
从第一性原理出发,IFB(Intermediate Functional Block)的出现是为了解决 Linux 内核网络栈中 “入站流量(Ingress)无法进行复杂流量调度” 的原生缺陷。
一、 IFB 的核心机制
在 Linux 内核中,流量控制(TC)主要设计用于 出口(Egress) 。
- Egress (出口) :拥有完整的队列调度器(Qdisc),可以实现 Shaping(整形) 、调度(Scheduling,如 HTB/FQ)和丢包管理。
- Ingress (入口) :只能进行 Policing(策略限制) 。
ingress qdisc本身没有缓冲区(Queue),它对包的处理逻辑非常简单:要么通过(Pass),要么直接丢弃(Drop)。
IFB 的工作原理:
IFB 是一个虚拟网卡驱动。它通过 tc 的 mirred 行动,将原本进入物理网卡(如 eth0)的入站数据包,“重定向”到 IFB 设备的出口路径上。
- 捕获:数据包到达
eth0的ingress钩子。 - 重定向:使用
tc filter ... action mirred egress redirect dev ifb0。此时,数据包从eth0的入站路径转到了ifb0的 出站队列(Egress Queue) 。 - 调度:在
ifb0的出口上,你可以挂载任何强大的 Qdisc(如 HTB, FQ_CoDel, CAKE)。 - 返回:经过
ifb0出口调度后的数据包,会被重新放回 Linux 网络协议栈,继续向上层传输。
二、 为什么 IFB 比直接 Drop(Policing)重传更少?
要理解这一点,必须对比 Policing(丢弃方案) 和 Shaping(整形方案,由 IFB 提供) 在 TCP 层面的表现。
1. 缓冲区(Buffer)的作用:吸收微突发(Micro-bursts)
-
Drop 方案 (Policing) :由于没有队列,它基于令牌桶算法。一旦短时间内包量超过桶的大小(Burst),多余的包会被立即丢弃。TCP 协议会将丢包视为严重的拥塞信号,触发快速重传和窗口减半。
-
IFB 方案 (Shaping) :由于 IFB 是在 Egress 路径,它拥有真正的 Queue(缓冲区) 。当微波流量超过额定速率时,IFB 不会立即丢包,而是将包暂时排队。
- 结果:TCP 发送方感知到的是延迟增加(RTT 变大) ,而不是丢包。TCP 拥塞控制算法(如 CUBIC 或 BBR)对延迟增加的反应远比丢包温和得多,从而避免了大规模重传。
2. 流量平滑(Smoothing vs. Clipping)
- Drop 方案:像一把“剪刀”,直接剪掉超出高度的部分(硬限速)。这种做法会导致 TCP 流量出现严重的“锯齿波”震荡。
- IFB 方案:像一个“漏斗”,将不规则的突发流量转化为平滑的流。
3. 主动队列管理(AQM)的支持
利用 IFB,你可以使用更智能的算法,例如 FQ_CoDel 或 ECN (Explicit Congestion Notification) :
- ECN 支持:IFB 上的 Qdisc 可以在检测到队列积压时,在 IP 头中打上 ECN 标记,而不是丢包。支持 ECN 的 TCP 发送方收到信号后会主动减速,重传率为零。
- 公平调度:如果多个 Pod 共享带宽,IFB 下的 FQ 算法可以确保小包(如 DNS/ACK)优先通过,防止大流(Bulk data)把所有带宽占满导致小连接超时重传。
三、 总结与事实依据
| 维度 | Ingress Policing (Drop) | IFB + Egress Qdisc (Shaping) |
|---|---|---|
| 队列(Queue) | 无 | 有(可配置深度) |
| 处理动作 | 超过即丢弃(Clips) | 超过则缓存/平滑(Smooths) |
| TCP 反应 | 频繁触发快速重传、降低窗口 | 增加 RTT,平滑调整发送速率 |
| 重传率 | 高(尤其是在突发流量下) | 低(利用缓存换取时间) |
| CPU 消耗 | 极低 | 较高(涉及虚拟设备上下文切换) |
针对你的场景(OpenStack/K8s 维护者):
虽然 IFB 效果好,但在高性能环境下,它的 上下文切换(Context Switch) 开销是不可忽视的。目前在云原生领域,如果你追求极致性能且想要 SNAT 前限速并减少重传:
- Cilium/eBPF:使用
EDT (Earliest Departure Time)模型。它不再依靠缓冲区排队,而是直接在 eBPF 中给每个包计算一个“允许发出的时间戳”,从底层改变了限速机制,既没有 IFB 的重定向开销,又能达到 Shaping 的效果。 - Kube-OVN:目前主要通过 OVS 的出口限速实现。
后续深入了解一下 eBPF EDT 是如何在没有 IFB 设备的情况下实现类似 Shaping 效果的?