ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

无损以太网与RoCEv2拥塞控制:PFC、ECN、DCQCN原理与实践

无损以太网与RoCEv2拥塞控制:PFC、ECN、DCQCN原理与实践 1. 为什么数据中心非要“无损”不可1.1 RoCEv2 对丢包零容忍做数据中心网络的人几乎都躲不开一个场景存储节点和计算节点之间跑的是 RoCEv2RDMA over Converged Ethernet version 2业务高峰期一到存储集群的 IOPS 曲线直接跳水时延从几十微秒飙到几百毫秒数据库主从复制开始告警。一开始很多人以为是存储盘坏了查来查去才发现问题出在网络丢包上。传统 TCP 对丢包的处理机制大家都很熟丢一个包等超时快速重传拥塞窗口减半慢启动重来。这一套在普通 Web 业务里完全够用但对 RDMA 来说就是灾难。RDMA 的设计目标是把数据从网卡直接搬到应用内存CPU 几乎不参与数据拷贝时延控制在微秒级。如果依赖网卡硬件重传不仅重传缓冲区开销巨大而且一旦出现丢包整个传输队列都要停下来等重传吞吐量直接腰斩。RoCEv2 网络里哪怕只有 0.1% 的丢包率有效带宽都可能降到原来的 50% 以下这个数字一点都不夸张我在实际压测中见过更惨烈的场景。所以 RoCEv2 要落地底层以太网必须提供一种“看起来不会丢包”的能力。这里的核心思路不是让链路永远不出现拥塞而是从交换机层面就不允许因缓冲区溢出而丢帧——也就是我们今天要聊的无损以太网。1.2 无损以太网不是“不会丢包”而是“不让交换机丢包”无损以太网Lossless Ethernet这个说法容易让人误解以为它是什么新的物理链路技术。其实它是在标准以太网基础上叠加了一套流量控制机制让交换机在缓冲区即将耗尽的时候不直接丢帧而是给对端发送暂停信号让对方先别发了等缓冲区腾出空间再继续。这套机制最早的形态是链路级别的 IEEE 802.3x PAUSE 帧实现方式很简单交换机检测到接收缓冲区超过阈值就向对端发一个 PAUSE 帧对端收到后停止发送一段指定时间。但 802.3x 有个致命问题——它是整条链路级别的暂停一旦触发这条链路上的所有流量全部停摆不管你是高优先级的存储流量还是低优先级的业务流量一视同仁。在混合部署的数据中心里这显然不可接受。于是 IEEE 802.1Qbb 标准即 PFCPriority-based Flow Control被提了出来。它的思路是把一条物理链路划分成最多 8 个优先级队列每个队列独立做流量控制某个队列拥塞了只暂停那个队列的发送其他队列完全不受影响。这样存储流量走优先级高的队列普通业务走优先级低的队列两者互不干扰无损能力就被精准地限制在需要的流量类型上。2. PFC无损网络的看门人2.1 PFC 工作机制与缓冲区原理PFC 的工作流程可以用一句话概括发水龙头关了供水系统才能不爆管。接收端的每个优先级队列维护一组阈值当占用超过一定水位通常是 XOFF 阈值就向对端发送一个 PFC 帧带着一个 16 位的暂停时间值单位是 pause quanta512 bit 时间。对端收到后对应优先级队列立即停止发送直到收到暂停值为 0 的 PFC 帧或者暂停定时器超时。这里面最关键的设计参数是缓冲区预算。交换机在规划无损队列时要保证从发送端收到 PFC 帧到它真正停止发送的这段时间里接收端不会爆缓冲区。这段延迟包括三部分接收端检测到拥塞并发出 PFC 帧的时间、帧在链路上的传播时间、对端解析并执行暂停的时间。把这些时间全部折算成字节数再乘以链路速率就是你需要预留的“动态缓冲区”大小。业界有一个经验公式缓冲预算 ≈ (链路延迟 交换机响应延迟 对端响应延迟) × 链路速率举个例子100Gbps 链路往返传播延迟约 2 微秒交换机 PFC 响应时间约 1 微秒对端响应时间约 1 微秒那么缓冲预算就是 4 微秒 × 100Gbps 50KB 左右。这只是单跳的静态预算如果网络里有n台交换机级联还要乘以n。这也是为什么无损网络的跳数规划特别重要——每多一跳需要的缓冲区就成倍增长而交换机的共享缓冲区是有限的不可能无限预留。实操中还有一个容易被忽略的细节PFC 队列必须做成无损队列但无损队列的数量是有限的。大多数数据中心交换机只能支持 2 到 4 个无损队列因为每个无损队列都要预留大量的专用缓冲区缓冲区是硬件资源不可共享。规划优先级时一定要克制不是所有流量都配得上无损队列。2.2 PFC 的三大副作用死锁、风暴、头阻塞PFC 不是一个完美的方案它把丢包问题暂时掩盖了但换来了三个更隐蔽的问题。副作用一PFC 死锁。如果网络拓扑里存在环路即使启用了生成树或等价多路径也无法完全避免某些极端情况下 PFC 暂停帧在环里循环传递——每个节点都在等对端停止发送导致所有端口相互暂停整张网陷入“抱死”状态。死锁一旦发生业务流量完全中断只能人工重启交换机队列。虽然现代交换机都有死锁检测机制能自动禁用某些队列但检测和恢复的时间窗口里业务已经受到了影响。副作用二PFC 风暴的连锁反应。当某个接收端频繁向上游发 PFC 暂停帧时上游队列被塞满上游自己也开始向下游其实是它的上游方向发 PFC 帧。这种暂停信号会沿着流量路径往源头方向逐跳扩散最终导致整个拥塞树上的流量全部被暂停。PFC 风暴的本质是拥塞的“多米诺骨牌效应”——本来只是一个端口的瞬时拥塞结果扩散成了多个交换机、多个端口的集体停摆。而且 PFC 帧本身是二层的控制平面通常不感知出了问题很难定位。副作用三头阻塞Head-of-Line Blocking。虽然 PFC 是逐优先级独立控制的但在同一优先级内部流量之间仍然互相干扰。设想一个场景优先级 3 上同时跑着存储写流量和存储读流量读流量是高优先级短报文写流量是普通大块数据。写流量拥塞触发了 PFC 暂停同队列的读流量也被殃及时延瞬间飙升。这在多租户云环境里特别常见不同业务共享同一个优先级队列互相干扰无法避免。我在生产环境踩过一次典型的 PFC 大坑一次存储节点固件升级后某个交换机的 PFC 队列收发包计数异常飙升大量 PFC 帧被疯狂发送隔壁机柜的普通业务也被拖慢。查了一整天才定位到是存储节点网卡驱动在升级后改变了 PFC 协商状态优先级映射全部错乱。那次之后我就养成了一个习惯——任何网卡、交换机固件的变更必须先检查 PFC 配置是否保持一致否则后面等着你的就是一场噩梦。3. ECN从“抢缓冲区”到“提前踩刹车”3.1 ECN 标记机制与 RED/WREDPFC 解决的问题是“交换机缓冲区满了怎么办”而 ECNExplicit Congestion Notification显式拥塞通知解决的问题更进一步——“网络快慢了怎么让发送端提前知道”。ECN 定义在 IP 头部的 ToS 字段中占用其中两个比特ECTECN-Capable Transport和 CECongestion Experienced。支持 ECN 的发送端在报文中设置 ECT 标记表明“我支持显式拥塞通知”。交换机采用加权随机早期检测WRED或类似算法对每个队列的占用深度进行采样——注意是采样不是全量统计——当队列占用超过最小阈值时开始以一定概率把经过的报文的 CE 位置 1队列占用越高标记概率越大超过最大阈值后100% 标记。接收端收到带 CE 标记的报文后不再依赖超时重传去感知拥塞而是主动通知发送端“网络堵了你该降速了”。在 RoCEv2 场景里标准做法是通过 CNPCongestion Notification Packet通知报文来传递这个信号。这样拥塞反馈的时延从“毫秒级超时”缩短到“微秒级 RTT”让发送端能够极其迅速地调整发送速率。ECN 的精妙之处在于它把拥塞控制从“事后补救”变成了“事前预警”。PFC 是等缓冲区快满了才动手相当于开车看到前面堵死了才急刹车ECN 是在缓冲区占用达到合理水位时就发出预警相当于透视到前面 500 米有缓行提前松油门滑行。3.2 ECN 永远替代不了 PFC理解 ECN 之后很多人会问既然 ECN 这么好能不能只用 ECN不用 PFC答案是不行。原因很直接ECN 的标记和反馈需要时间。发送端从收到 CE 信号、发出 CNP 报文、到真正降低发送速率至少需要一到两个 RTT。在这段时间里如果交换机缓冲区已经被占满报文依然会被无条件丢弃。PFC 是最后一道防线确保在 ECN 反馈生效之前交换机绝对不丢帧。两者是互补关系——ECN 负责“长期调优”PFC 负责“兜底保底”。这个逻辑对应到 RoCEv2 的端到端拥塞控制协议上就是 DCQCN 出场了。4. DCQCN看得见的拥塞控制大脑4.1 DCQCN 的三组件框架RP、NP、CPDCQCNData Center Quantized Congestion Notification是微软提出的、专为 RoCEv2 设计的端到端拥塞控制协议。它脱胎于 QCNIEEE 802.1Qau但针对以太网和 RDMA 的场景做了大量调整。整个框架分为三个角色RPReaction Point发送端负责根据拥塞信号调整发送速率。NPNotification Point接收端负责检测 CE 标记并生成 CNP 报文。CPCongestion Point交换机负责通过 WRED/ECN 标记拥塞报文。整个链路是这样运转的发送端RP以当前速率发送带 ECT 标记的数据交换机CP检测到队列拥塞后以一定概率把报文标记为 CE接收端NP收到 CE 报文后知道“网络堵了”立刻生成一个 CNP 报文回送给发送端发送端收到 CNP 后触发拥塞控制算法降低发送速率。这里有个容易被忽略的细节CNP 报文的优先级必须高于数据流量。如果 CNP 和普通数据跑在同一个优先级队列里CNP 本身就可能被 PFC 暂停拥塞信号传不回去整套控制机制直接失效。部署 RoCEv2 时必须为 CNP 单独分配一个高优先级 QoS 队列这个设计不是为了“更快的反馈”而是为了“保证反馈可达”。4.2 DCQCN 速率调整的核心机制DCQCN 的发送端收到 CNP 后会经历一个“快速降速、缓慢恢复”的过程这个设计精妙地平衡了吞吐量和延迟。第一阶段是降速Rate Decrease发送速率乘以一个系数1/2可配置默认是减半下限由Rmin决定。这个操作非常激进目的就是立刻切断拥塞源头。第二阶段是增速Rate Increase采用类似 TCP 的加性增加策略每收到一个确认报文ACK速率加上一个固定步长Rai但每 N 个 ACK 才恢复一小步保证速率不会突然飙升再次引发拥塞。不过 DCQCN 真正的精髓在于BCN 定时器机制。如果没有拥塞信号发送端并不是一直不变而是通过一个定时器Bcn默认约 1 微秒周期性做“小幅提速试探”如果网络没有出现新的 CNP就继续缓慢加速一旦收到 CNP再快速降速。这种“慢涨快跌”的策略让网络吞吐量能够在拥塞消失后自动恢复到较高水平同时尽量少产生新的拥塞。DCQCN 还有一个关键参数是G——CNP 反馈的强度也就是接收端每收到多少个 CE 报文才生成一个 CNP。如果G太大拥塞信息传递不及时如果G太小CNP 报文过多占用了带宽和 CPU。从实测来看G 通常设置在 0.01 到 0.1 之间具体值取决于链路速率和报文大小得靠压测来标定。注意DCQCN 的参数不是越“激进”越好。我曾经把速率降低因子从 1/2 调成 1/4希望拥塞时能更快降速结果因为降速过度反而导致交换机的队列始终无法填满吞吐量掉了一半。调参的时候要综合考虑不能只看某一个指标。4.3 DCQCN 和参数调优的实践心得在真实部署中DCQCN 的调优主要围绕以下参数参数作用常见初始值调优建议GCNP 生成概率0.01~0.1链路速率越高、时延越大取更小值Bcn无损队列的加速定时器1~10 微秒结合链路的 RTT 调整Rmin最低发送速率10~100 Mbps不能太低否则小流被饿死Rai增步长视缓冲区预算而定在无拥塞时增大以提升带宽恢复速度alpha拥塞因子/平滑系数默认影响计算拥塞程度的平滑程度调参的顺序我建议是先稳定再性能。先把 ECN 的 WRED 阈值配好保证交换机在缓冲区占用 60% 左右开始标记再调 DCQCN 的降速步长和回复周期。如果一上来就追求极限吞吐很容易把网络打挂。还有一个重要的检查项RoCEv2 流量通常会要求网卡开启 PFC 和 ECN 的支持但每个网卡厂商的默认策略不同。MellanoxNVIDIA网卡默认支持 DCQCN而 Broadcom 网卡可能需要手动开启。部署前一定要确认驱动版本和固件版本支持你想要使用的拥塞控制协议。5. 拥塞可视化把看不见的“网络堵点”揪出来5.1 为什么要可视化仅仅有计数器还不够PFC、ECN、DCQCN 都是_数据平面_的机制它们能不能正常工作需要用_管理平面_的工具来实时观察。拥塞可视化的核心价值是让你在网络故障发生前就提前感知风险而不是等业务报了警再去救火。我遇到过太多类似的案例业务团队报“存储时延高”网络团队查交换机 CPU、查端口流量全部正常最后发现是某个端口的 PFC 暂停计数在持续增长只是没有人看这些计数器。等到 PFC 计数增长到每秒几百万次的时候业务早就慢成狗了。PFC 计数是网络拥塞的“煤矿里的金丝雀”早该成为日常监控的核心指标。5.2 可视化需要关注的核心指标拥塞可视化的指标可以分为三层第一层PFC 层指标pfcTxCount/pfcRxCount端口上发送和接收的 PFC 帧数量。pfcRxCount持续偏高说明对端正在频繁暂停你pfcTxCount持续偏高说明你正在频繁暂停对端。pfcDropCount因 PFC 队列溢出而丢弃的帧数。一旦出现pfcDropCount非零说明 PFC 缓冲区预算已经不足属于严重故障。第二层ECN 层指标ecnMarkedPackets交换机标记为 CE 的报文数量。这个指标能反映拥塞的_发展趋势_。WRED 丢弃计数虽然无损网络理论上不应该丢包但因为 ECN 标记只对支持 ECN 的流量生效一些不支持 ECN 的低优先级流量依然可能被 WRED 丢弃。第三层DCQCN 层指标CNP 发送/接收计数接收端每生成一个 CNP都会对应发送端的一次降速动作。CNP 频率过高意味着网络持续拥塞发送端的速率调节在频繁触发。队列深度交换机队列的实时占用情况可以从 SNMP 或者流采样里读出来。我个人在搭建监控时最常用的组合是端口级别的 PFC 计数器 ECN 标记计数 RDMA 网卡的 CNP 计数。这套组合能覆盖从“物理层链路拥塞”到“协议层反馈”整个链路定位问题非常快。5.3 实战案例一次存储超时报警的完整排查去年我处理过一个很有意思的问题。某个客户的一套存储集群每两周固定出现一次 IO 超时业务影响很大但每次持续大约十分钟就自动恢复始终复现不出来。我们先加了针对性的监控项把每个存储相关端口的 PFC 计数器、ECN 计数器和 CNP 计数器全部采集下来采样周期 30 秒一次连续监控一周。结果抓到了一个规律超时发生前 5 分钟某个交换机的某个端口ecnMarkedPackets开始飙升紧接着pfcTxCount也开始增长之后就是 CNP 计数爆表再然后业务就超时了。顺着 ECN 标记的来源查下去发现那个端口连接的是存储节点的双活网卡而这个节点的负载均衡策略有问题——它把所有的高优先级流量都打到了同一条链路上导致这条链路的队列深度在每次备份任务启动时瞬间爆表。虽然 ECN 在尽力标记DCQCN 在拼命降速但拥塞发生得太快、太猛PFC 缓冲区最终还是被打穿出现了丢帧RDMA 重传超时业务直接中断。排查出问题后修了两个地方一是调整了网卡的负载均衡策略把流量分摊到两条物理链路上二是优化了交换机上 ECN 的 WRED 最小阈值让 ECN 在队列占用 40% 的时候就提前开始标记给 DCQCN 争取更多降速时间。上线后连续观察一个月PFC 和 ECN 计数都回到了极低水平存储超时告警再也没出现过。这个案例给我最大的启发是丢包只是一系列连锁反应的最后一步数据平面里 PFC、ECN 的变化才是这个链条上的早期信号。如果你的监控系统只盯着丢包率那你注定要等问题发生后才能感知到网络故障。5.4 可视化工具盘点真实机房环境里没有任何一个工具能覆盖所有场景。我常用的工具组合是交换机命令行Cisco、华为、Arista 都支持show qos pfc类似的命令能看到每个端口的 PFC 实时计数排查问题最快。SNMP MIB 采集适合长期监控把 PFC/ECN 计数器采集到 Prometheus、Zabbix 这类时序数据库配上 Grafana 面板做可视化。RDMA 网卡计数器通过rdma statistic或厂商的工具如 NVIDIA 的mlxstat直接读取网卡侧的 CNP、CE 计数能验证端到端拥塞链路是否闭环。NetFlow/sFlow 流采样如果交换机支持可以把高优先级队列的流量占比采样下来用来辅助判断到底是哪条流在制造拥塞。可视化面板上我建议至少放四张图PFC 计数按端口、ECN 标记趋势、CNP 频率、队列深度热力图。这四张图配合起来基本能在一分钟内判断出一个网络节点是安全的、拥塞的、还是已经出现丢包。6. 结尾从“能用”到“看得清”才算真正掌握我做了这么多年数据中心网络最大的感触是——无损以太网这套东西光知道理论是远远不够的必须亲手调过参数、亲眼看过 PFC 计数器飙升、亲眼看 CNP 风暴把业务打崩才能真正理解它每一步设计背后的意义。最后再分享一个小技巧搭建实验环境时不要只在小规模测试床上验证功能尽量模拟多跳拓扑——比如三台交换机串起来跑 RoCEv2 存储流量。因为很多 PFC / ECN 的问题只在多跳场景下才会暴露出来单跳验证通过了不代表上线没问题。我就吃过这个亏单跳测试一切正常上线后跨机柜流量一出问题才发现多跳拓扑下的缓冲区预算完全算错了。如果你也要调无损以太网记住一点先做监控、再调参数、最后才做优化。没有可视化的网络就像蒙着眼睛开车出了事连方向都不知道。这篇文章就写到这里下一篇我会专注讲讲 RoCEv2 场景下的 QoS 队列规划包括优先级映射、流量整形和测试验证方法感兴趣的话可以继续看。
返回列表