ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

IEEE 802.1Qcr-2020 ATS异步流量整形:从标准到交换机配置实战

IEEE 802.1Qcr-2020 ATS异步流量整形:从标准到交换机配置实战 简介IEEE 802.1Qcr-2020.pdf 是 TSN 协议族中关于异步流量整形Asynchronous Traffic Shaping的官方标准文档面向从事工业自动化、汽车电子、航空航天及电信网络研发的工程师与协议研究者用于解决传统以太网在实时性与确定性传输上的不足。该标准为 IEEE 802.1Q-2018 的第 34 次修订整合了 Qcp、Qcc、Qcy、Qcx 等多项更新定义了桥接设备与端点在恒定比特率全双工链路上执行异步流量整形的程序和管理对象涵盖流量整形算法、优先级队列管理、时隙分配、流量监管、带宽预留及故障恢复机制并给出基于 SNMP 等协议的管理配置接口。资源包共 1 个 PDF 文件约 2.8MB内容为完整标准正文便于按章节查阅术语定义、程序流程与管理对象结构。目前已有 703 人学习下载适合需要深入理解 TSN 流量整形机制、对照标准开展协议实现或方案设计的读者参考。1. 从一次车载以太网丢包说起IEEE 802.1Qcr-2020 到底解决了什么去年帮一个做智能座舱的团队排查 TSN 网络抖动现象很怪交换机在流量突发时会把异步流量整段丢掉而不是像预期那样平滑降速。抓了半个月的包才定位到问题出在他们用的交换机只实现了 802.1Qav 的信用整形没有支持异步流量的队列聚合机制。这个坑让我重新翻出了 IEEE 802.1Qcr-2020 这份标准文档——它定义的 Asynchronous Traffic ShapingATS异步流量整形正是用来补上传统 TSN 整形机制在异步场景下的短板。如果你正在做车载以太网、工业实时网络或者音视频桥接手头只有 Qav 那套信用整形方案遇到突发流量丢包、延迟抖动压不下去的情况这份 PDF 就是绕不开的参考。它不厚但信息密度极高属于那种“看一遍能改架构、看两遍能写驱动”的硬核资料。2. 拆开 802.1Qcr 的整形模型ATS 和 Qav 到底差在哪2.1 为什么需要异步流量整形传统 TSN 的时间敏感流量调度依赖两类机制一类是基于时间门控的 802.1Qbv需要全网时钟同步配置复杂另一类是基于信用值的 802.1Qav靠“信用累积—消耗”来平滑流量但它有个硬伤——信用整形本质上是速率控制对突发流量的响应是滞后的。当多个异步流同时涌入同一个出端口Qav 的信用机制会让队列长度剧烈波动极端情况下直接触发尾丢包。802.1Qcr 提出的 ATS 换了个思路不再依赖全局时间同步也不单纯靠信用累积而是给每个流或每组流维护一个“令牌桶 虚拟调度器”的组合模型。每个流有独立的整形参数出端口按 Eligibility Time合格时间来决定什么时候放行一个帧。这个 Eligibility Time 是根据流的承诺速率和突发容限算出来的相当于给每个流发了一张“最早可发送时间表”。这样一来即使多个流同时到达交换机也能按各自的整形参数错开发送避免瞬时拥塞。从选型角度看如果你的网络里异步流量占比高、流量模式不可预测、又不想引入 PTP 全网同步的复杂度ATS 是比 Qav 更合适的选择。代价是交换机需要维护每个流的整形状态对硬件资源有一定要求但 2020 版标准里已经给出了聚合整形的方案可以把多个流映射到同一个整形器降低实现成本。2.2 ATS 的核心参数与计算逻辑标准里定义了几个关键参数理解它们才能配出合理的整形器。下面这张表是我从文档第 8 章和第 9 章整理出来的核心参数对照参数名含义典型取值参考Committed Information Rate (CIR)流的承诺信息速率根据流带宽需求设定如 10 MbpsCommitted Burst Size (CBS)承诺突发量通常设为最大帧长的 2~4 倍Peak Information Rate (PIR)峰值信息速率可等于 CIR 或略高Peak Burst Size (PBS)峰值突发量不小于 CBSEligibility Time帧最早可发送时间由整形器动态计算Empty Queue Time队列空置时间用于重置整形状态计算 Eligibility Time 的核心公式在标准第 8.6.3 节简化后的逻辑是对于每个到达的帧根据其所属流的 CIR 和 CBS计算出一个“合格时间”只有当前时间超过这个合格时间帧才被允许进入调度队列。如果多个帧同时合格则按优先级或轮询方式调度。我一般会先用一个简单的 Python 脚本模拟一下整形效果确认参数合理后再去配交换机。下面这段代码模拟了单流的 ATS 整形过程输入是帧到达时间序列和帧长输出是每个帧的实际发送时间# ATS 单流整形模拟 # 输入帧到达时间列表、帧长列表、CIR、CBS # 输出每个帧的合格时间与发送时间 def ats_shaper(arrival_times, frame_sizes, cir, cbs): arrival_times: 帧到达时间列表单位微秒 frame_sizes: 帧长列表单位字节 cir: 承诺信息速率单位 Mbps cbs: 承诺突发量单位字节 # 将 CIR 转换为 字节/微秒 cir_bytes_per_us cir * 1e6 / 8 / 1e6 # Mbps - bytes/us eligibility_times [] last_eligibility 0.0 token_bucket cbs # 初始令牌桶满 for i, (t_arrival, size) in enumerate(zip(arrival_times, frame_sizes)): # 令牌桶按时间补充 if i 0: delta_t t_arrival - arrival_times[i-1] token_bucket min(cbs, token_bucket delta_t * cir_bytes_per_us) # 判断是否有足够令牌 if token_bucket size: token_bucket - size eligibility t_arrival else: # 令牌不足计算需要等待的时间 deficit size - token_bucket wait_time deficit / cir_bytes_per_us eligibility t_arrival wait_time token_bucket 0 # 合格时间不能早于上一个帧的合格时间 eligibility max(eligibility, last_eligibility) eligibility_times.append(eligibility) last_eligibility eligibility return eligibility_times # 测试10 个帧到达时间间隔不均匀 arrivals [0, 5, 12, 20, 35, 50, 80, 120, 200, 300] sizes [1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500] cir 10 # 10 Mbps cbs 6000 # 6000 字节 result ats_shaper(arrivals, sizes, cir, cbs) for i, (a, e) in enumerate(zip(arrivals, result)): print(f帧{i}: 到达 {a}us, 合格 {e:.2f}us, 延迟 {e-a:.2f}us)这段代码的逻辑说明令牌桶按 CIR 速率补充初始满桶为 CBS。每个帧到达时先检查令牌是否足够足够则立即合格否则计算需要等待的时间。最后用max(eligibility, last_eligibility)保证合格时间单调递增避免乱序。参数调整时重点看 CIR 和 CBS 的比值——CIR 越小、CBS 越大突发容忍度越高但平均延迟也会上升。实际配置交换机时CIR 通常设为流的平均速率CBS 设为最大帧长的 2 到 4 倍具体要看流量模型。2.3 聚合整形与每流整形的取舍标准里给了两种实现方式每流整形per-stream shaping和聚合整形aggregate shaping。每流整形精度高但交换机需要为每个流维护独立状态流数量多的时候硬件资源吃紧。聚合整形把多个流映射到同一个整形器共享 CIR 和 CBS实现简单但会引入流间干扰。我一般会这样选流数量少于 100 且对延迟敏感的场景用每流整形流数量大、流量模式相近的场景用聚合整形但要把同一优先级、同一速率等级的流聚在一起。标准第 9 章给了聚合整形的映射规则核心是保证聚合后的 CIR 不小于各流 CIR 之和CBS 不小于各流 CBS 之和。如果配错了会出现某个流被“饿死”的情况——现象是低优先级流长时间得不到发送机会抓包看它的合格时间一直被推后。3. 把标准落到交换机配置从参数计算到验证的完整链路3.1 从流量特征反推整形参数拿到一份流量抓包怎么定 CIR 和 CBS我的习惯是先用 Wireshark 导出流的到达时间序列和帧长分布然后算三个值平均速率、最大突发量、95 分位延迟要求。平均速率用来定 CIR最大突发量用来定 CBS延迟要求用来验证参数是否合理。举个例子某个车载摄像头流抓包 10 秒总共 12000 个帧平均帧长 1200 字节总字节数 14.4 MB平均速率约 11.5 Mbps。最大突发是在 50ms 内到达了 200 个帧突发量约 240 KB。如果延迟要求是 2ms 以内那么 CIR 设 12 Mbps、CBS 设 240 KB 就偏大了——240 KB 的突发在 12 Mbps 下需要 160ms 才能发完延迟肯定超标。这时候要么提高 CIR要么把 CBS 降到 20 KB 左右让整形器把突发摊平到更长时间。下面这个脚本用来从抓包导出的 CSV 计算这些指标import pandas as pd import numpy as np # 读取抓包导出的 CSV包含 time 和 frame_len 两列 df pd.read_csv(stream.csv) df[time] df[time].astype(float) df[frame_len] df[frame_len].astype(int) # 总时长和平均速率 duration df[time].max() - df[time].min() total_bytes df[frame_len].sum() avg_rate_mbps total_bytes * 8 / duration / 1e6 print(f总时长: {duration:.3f}s, 平均速率: {avg_rate_mbps:.2f} Mbps) # 滑动窗口找最大突发窗口 10ms window 0.01 df[cum_bytes] df[frame_len].cumsum() max_burst 0 for i in range(len(df)): t_start df[time].iloc[i] t_end t_start window mask (df[time] t_start) (df[time] t_end) burst df.loc[mask, frame_len].sum() if burst max_burst: max_burst burst print(f10ms 窗口最大突发: {max_burst} 字节) # 建议 CIR 和 CBS suggested_cir avg_rate_mbps * 1.2 # 留 20% 余量 suggested_cbs max_burst * 0.5 # 突发量减半用整形摊平 print(f建议 CIR: {suggested_cir:.2f} Mbps, 建议 CBS: {suggested_cbs:.0f} 字节)逻辑说明先算平均速率作为 CIR 的基准再留 20% 余量应对流量波动。CBS 取最大突发的一半目的是让整形器把突发分散到多个调度周期而不是一次性放行。参数说明窗口大小 10ms 是经验值对应大多数 TSN 交换机的调度周期如果交换机调度周期是 1ms窗口也要相应调小。这个脚本的输出只是起点最终参数要在实际设备上跑一遍看延迟和丢包是否达标。3.2 在 Linux 上用 tc 模拟 ATS 行为没有硬件交换机的时候可以用 Linux 的 tc 工具模拟 ATS 的整形效果。虽然 tc 的 TBF令牌桶过滤器不是标准意义上的 ATS但可以用来验证参数是否合理。下面这条命令在 eth0 上创建一个 TBF 队列速率 12 Mbps突发 20 KB延迟 2ms# 清除现有队列规则 tc qdisc del dev eth0 root 2/dev/null # 添加 TBF 队列模拟 ATS 整形 tc qdisc add dev eth0 root handle 1: tbf \ rate 12mbit \ burst 20kb \ latency 2ms # 查看队列状态 tc -s qdisc show dev eth0参数说明rate对应 CIRburst对应 CBSlatency是最大允许延迟超过这个值的帧会被丢弃。tc -s输出的dropped计数就是整形器丢掉的帧数如果这个数在涨说明 CBS 太小或者 CIR 太低。我一般会先用 iperf3 打流观察 dropped 和延迟再微调参数。注意 tc 的 TBF 是单队列的不能区分流只能验证整体整形效果真要验证每流整形还是得上支持 ATS 的交换机。3.3 验证整形效果看什么指标、怎么判断配完参数后验证分三步第一步看丢包率整形器的 dropped 计数应该为 0 或极低第二步看延迟分布用 ping 或专用测试仪测端到端延迟95 分位应该满足要求第三步看队列长度如果队列长期处于高位说明 CIR 偏低或 CBS 偏大。我常用的验证命令组合# 持续 ping 测试延迟 ping -c 1000 -i 0.01 -s 1200 192.168.1.100 | tail -5 # 用 iperf3 打流测试吞吐和丢包 iperf3 -c 192.168.1.100 -u -b 12M -t 60 -l 1200 # 查看接口队列统计 tc -s qdisc show dev eth0 ip -s link show eth0判断标准ping 的 95 分位延迟不超过整形延迟上限的 1.5 倍iperf3 的丢包率低于 0.01%tc 的 dropped 计数为 0。如果延迟超标优先降 CBS如果丢包优先升 CIR。这两个参数是跷跷板要反复调几次才能找到平衡点。4. 避坑与排查ATS 落地时最容易翻车的五个地方4.1 现象配置完 ATS 后低优先级流完全发不出去原因聚合整形的 CIR 设置过低多个流共享一个整形器时高优先级流把令牌耗尽低优先级流永远等不到合格时间。标准里虽然给了聚合规则但没强制要求实现者做公平调度。解决检查聚合组的 CIR 是否大于等于各流 CIR 之和如果流数量多考虑拆成多个聚合组或者改用每流整形。临时缓解可以把低优先级流单独映射到一个整形器。4.2 现象抓包看帧的合格时间比到达时间晚很多延迟抖动大原因CBS 设得太大整形器允许大量突发一次性合格导致后续帧的合格时间被推后。这是令牌桶整形的固有特性——突发容忍度和延迟是矛盾的。解决把 CBS 降到最大帧长的 2 到 4 倍重新测试延迟。如果业务允许一定丢包可以同时开队列丢弃策略让超出突发的帧直接丢掉而不是排队。4.3 现象交换机重启后整形参数丢失流量恢复成未整形状态原因很多交换机的 ATS 配置是运行时配置没有写进启动配置。标准里没有规定配置持久化机制这是实现层面的问题。解决配置完后执行保存命令不同厂商命令不同常见的是write memory或copy running-config startup-config并在重启后验证show running-config里是否有 ATS 相关配置。我一般会在自动化脚本里加一步配置校验防止漏保存。4.4 现象不同厂商交换机对接时ATS 行为不一致原因802.1Qcr 标准给了多种实现选项比如 Eligibility Time 的计算精度、聚合整形的映射方式不同厂商选的可能不一样。标准只保证互操作性不保证行为完全一致。解决对接前先确认双方支持的 ATS 模式每流还是聚合、参数范围、时间精度。如果差异大考虑在边界设备上做流量整形把内部网络的整形策略统一。实在不行就退回 Qav虽然效果差一点但互操作性更好。4.5 现象用 tc 模拟时延迟正常换到真实交换机后延迟翻倍原因tc 的 TBF 是软件整形调度周期和硬件交换机不同。硬件交换机的调度周期通常是 1ms 或 125us而 tc 的调度精度受内核时钟影响可能更细或更粗。另外硬件交换机的队列管理、缓存大小也和 Linux 不一样。解决不要把 tc 的测试结果直接当成硬件配置的依据它只能用来验证参数趋势。真实参数要在目标硬件上跑用测试仪或高精度抓包工具测端到端延迟。我一般会留 30% 的余量比如 tc 上测出 1ms 延迟硬件上按 1.3ms 来配。5. 进阶技巧用 Eligibility Time 做跨域协同整形标准第 10 章提到了一个容易被忽略的用法Eligibility Time 可以跨域传递。也就是说上游交换机算出的合格时间可以编码到帧里比如用 VLAN 标签的某几位下游交换机直接复用这个时间不需要重新计算。这样做的好处是端到端延迟更可预测因为整段路径上的整形器共享同一个时间基准。实现上需要在入口交换机做流分类和整形参数映射把流的 CIR、CBS 和计算出的 Eligibility Time 写入帧的元数据。中间交换机只做转发和更新出口交换机根据最终时间调度。标准里没有规定具体的编码格式这部分通常由厂商自定义所以跨厂商部署时要在边界做转换。我自己的习惯是先在单台交换机上把每流整形调稳再逐步扩展到多台每加一台就重新测端到端延迟。不要一次性全网铺开否则出了问题很难定位是哪一跳的整形参数不对。另外Eligibility Time 的精度要统一如果上游用微秒、下游用纳秒换算时容易出舍入误差我一般会在配置脚本里强制统一单位。从那以后我每次配 ATS都会先用脚本算一遍参数再在测试环境跑 24 小时稳定性确认 dropped 为 0、延迟 95 分位达标后才上生产。这套流程帮我省了不少半夜爬起来排查的麻烦。希望帮到你。本文还有配套的精品资源点击获取
返回列表