为什么限速100Mbps,却能瞬间跑到500Mbps?——一次运营商QoS误判,彻底理解DPDK rte_meter 与 Token Bucket(下)

📅 2026/7/14 10:39:50 👁️ 阅读次数 📝 编程学习
为什么限速100Mbps,却能瞬间跑到500Mbps?——一次运营商QoS误判,彻底理解DPDK rte_meter 与 Token Bucket(下)

在上一部分:为什么限速100Mbps,却能瞬间跑到500Mbps?——一次运营商QoS误判,彻底理解DPDK rte_meter 与 Token Bucket(上)-CSDN博客

我们已经确认:

  • rte_meter工作完全正常;
  • Token Bucket并没有"失效";
  • 客户看到的500Mbps峰值,其实来源于提前积累的Token。

但是,一个新的问题又出现了。

如果允许一直积累Token,那是不是用户永远都可以突破带宽限制?

答案当然不是。

真正控制这一切的,就是Token Bucket中的几个关键参数。


十一、为什么必须限制Bucket容量?

很多开发者第一次实现Token Bucket时都会写成:

按照100Mbps不断产生Token

这样看起来没有任何问题。

但是如果:Token能够无限增长。

例如:

一天没有任何流量 ↓ 积累几十GB Token ↓ 第二天 瞬间发送几十GB

那么:QoS就彻底失去了意义。

因此。

所有Token Bucket都会规定:Bucket容量(Bucket Size)

超过容量以后,新的Token直接丢弃。

也就是说:

Token ↓ Bucket满 ↓ 停止累积

这就是:Burst 为什么一定是有限的。


十二、CBS到底是什么?

很多人在DPDK里面第一次看到:

cbs

都会理解成缓存。

其实不是。

CBS全称:Committed Burst Size

中文通常翻译:承诺突发容量。

它表示:

最多允许积累多少合同带宽对应的Token。

例如:

配置:

CIR =100Mbps CBS =1MB

那么:一分钟没有业务。

Bucket里面也最多只有1MB。

不会继续增长。

所以。

真正允许突发的数据量。

不是一分钟积累多少。

而是CBS决定。


十三、trTCM为什么又多了PIR?

上一节我们提到:

DPDK支持:

srTCM

以及:

trTCM

很多人都会问:

为什么还需要第二种?

答案就在于运营商真正卖的不是一个带宽。

而是两个带宽。

例如:企业专线。

合同:

保证: 100Mbps

但是:

允许峰值200Mbps。

于是。

QoS就出现两个概念。

参数含义
CIR保证带宽(Committed Information Rate)
PIR峰值带宽(Peak Information Rate)

对应两个Bucket:CBS、PBS。

整个模型如下:

只有两个Bucket共同工作。

才能真正实现运营商合同。


十四、Green、Yellow、Red到底怎么来的?

很多人认为:

三种颜色是三个速率。

其实不是。

真正过程,例如:

收到一个1500Byte数据包。

第一步检查Peak Bucket。

如果Peak Token都不够。

立即:

Red

如果Peak足够。

继续检查Committed Bucket。

如果Committed也足够。

就是:

Green

否则就是:

Yellow

整个判断。

只有几十条CPU指令。

没有任何等待。

没有任何Sleep。

这也是DPDK能够百万级Flow。

仍然高速Meter真正原因。


十五、DPDKrte_meter为什么能够做到每包计量?

很多人第一次阅读:librte_mete源码。

都会觉得每个包都要更新时间、更新Token、计算颜色。

为什么还能100G?

原因就在于:它并没有周期性刷新Token。

真正实现采用的是:惰性更新(Lazy Update)。

也就是说。

不会每1毫秒更新一次。

而是收到数据包才计算距离上次过去了多久。

例如:

last_time ↓ 当前时间 ↓ delta ↓ 新增Token ↓ 更新Bucket

如果一分钟没有包。

CPU什么都不做。

下一包到来,一次补齐一分钟所有Token。

因此。时间复杂度始终O(1)。


十六、为什么测速必须持续30秒以上?

很多客户测速:

喜欢点击开始。

看到第一秒500Mbps。

立即截图、投诉。

实际上运营商真正验收通常要求持续30秒甚至60秒。

原因就在于前几秒消耗的是CBS里面提前积累的Token。

随着Bucket逐渐耗尽。

系统开始只能按照CIR补充Token。

于是测速曲线开始下降。

最终稳定100Mbps。

真正符合合同。

因此QoS验收从来不是看瞬时速率。

而是:长期平均速率。


十七、研发团队最终是如何定位问题的?

研发团队最终抓取Meter统计信息。

发现:

整个测速过程呈现如下变化:

时间GreenYellowRed
0~2 秒大量少量0
2~5 秒减少增加少量
5 秒以后基本稳定少量稳定增长

与此同时。

出口平均带宽逐渐稳定:

101 Mbps

这说明:

Meter始终按照RFC2698正常工作。

客户看到的500Mbps只是Burst。

而不是长期带宽。


十八、DPDK工程实践中的几个误区

实际项目中,rte_meter使用最容易踩的几个坑包括:

误区一:把Meter当成限速器。

rte_meter不会阻塞数据包,也不会控制发送节奏,它只负责完成流量计量并返回颜色。

误区二:CBS配置过大。

CBS越大,允许的突发越大。配置不合理时,用户测速会看到很高的瞬时速率,从而误认为限速失效。

误区三:每个数据包都重新初始化Meter。

Meter对象必须保存每个业务流的状态(Token、时间戳等),不能每处理一个包就重新创建,否则计量结果完全错误。

误区四:把Meter和Scheduler混为一谈。

Meter负责"判定",Scheduler负责"执行"。两者职责完全不同。


十九、Meter之后为什么还需要Scheduler?

到这里很多读者又会产生新的疑问。

假设:Meter已经返回:

Green

或者:

Yellow

下一步怎么办?

实际上。

Meter根本不会发送。也不会排队。

它只是告诉后面的QoS模块:

这个包是什么颜色。

真正决定:什么时候发送?什么时候丢弃?什么时候降优先级?

全部属于Scheduler。

这也是DPDK为什么把QoS拆成两个库。

librte_meter

负责:Traffic Metering。

librte_sched

负责:Traffic Scheduling。

二者共同组成完整QoS。


二十、写在最后

很多开发者第一次接触QoS时,都会把"限速"理解成"超过100Mbps立即禁止发送"。事实上,现代运营商QoS遵循的是SLA思想,它关注的是长期平均速率,而不是每一个瞬间的发送速度。

librte_meter正是这一思想的高性能实现。它依据RFC2697、RFC2698和RFC4115,通过Token Bucket模型完成每个数据包的流量计量,并返回Green、Yellow、Red三种颜色,而不是直接控制发送行为。

真正的QoS流程应该理解为:

Packet │ ▼ Meter(计量) │ ▼ Color(Green / Yellow / Red) │ ▼ Scheduler(调度) │ ▼ Queue(排队) │ ▼ NIC发送

因此,当客户反馈"100Mbps为什么能跑到500Mbps"时,首先应该分析的是CBS、PBS以及Burst配置,而不是怀疑Meter是否失效。