遇到过这样一种场景吗网卡是 NVIDIA CX6 系列交换机是华为 CE 系列物理链路全通IP 也能 ping 通但一跑 RDMA带宽怎么都上不去CPU 占用却不低。我第一次在存储集群上调 RDMA 时就卡在这个状态。后来费了不少功夫才明白问题并不是出在网卡驱动版本而是整个网络还没有为 RDMA 准备好无损传输。RDMA 走高带宽低延迟但它非常怕丢包而传统的尽力而为以太网并不会主动保证不丢包。所以需要 PFCPriority Flow Control优先流控制和 DCQCNData Center Quantized Congestion Notification数据中心量化拥塞通知配合构建一条无损链路。这篇文章就把我在 CX6 网卡和华为 CE 交换机上使能 DCQCN 与 PFC 的完整过程、配置要点和踩坑记录写清楚给同样在推 RoCE 网络的朋友一个参考。1. 先搞清楚为什么 RDMA 离了 PFC 和 DCQCN 就“跑不动”1.1 一个丢包引发的“血案”RDMARemote Direct Memory Access允许数据直接从一个节点的内存传输到另一个节点的内存绕过 CPU 和内核协议栈。在 RDMA 的通信模型里QPQueue Pair是最基础的概念。一个 QP 本质上是发送队列和接收队列的组合两个端点建立连接后通过 QP 来收发消息。你可以把 QP 粗浅地理解成 TCP 连接但它的工作路径完全在网卡硬件里CPU 不参与数据搬运。传统 TCP 在丢包时依靠 ACK 超时和重传吞吐还能勉强维持但 RDMA 的数据传输走的是硬件快速路径可靠性机制相对简单。丢包会导致重传风暴、NACK 风暴甚至 QP 状态机进入 error 状态。曾经有个实验结论RoCE 在 1% 丢包率下带宽会跌去 80% 以上原因就在于拥塞恢复机制失效发送端不断重试已经传过的报文。我实际调 RDMA 时拿着网卡跑ib_write_bw却发现带宽只有 20Gbps而物理链路明明显示 100Gbps。一开始怀疑光纤问题换了线缆没用后来看了网卡统计rx_packets里大量关联重传计数才反应过来链路丢包严重根本不是线速问题。TCP 丢包后缓慢线性恢复RDMA 丢包后却可能雪崩式恶化。1.2 以太网、InfiniBand 和 RoCE 三者关系InfiniBand 原生无损因为它从链路层就设计了基于 credit 的流控机制但这套网络和以太网不通用成本和生态也让人望而却步。RoCE 让 RDMA 跑在以太网上用更低的成本复用现有网络。RoCE 有两个版本RoCE v1二层协议只能工作在同一个 VLAN 内不能跨三层路由。RoCE v2把报文封装成 UDP 格式可以跨三层路由是目前数据中心的主流选择。CX6 支持 RoCE v1/v2华为 CE 交换机的无损配置也主要围绕 RoCE v2 展开。RoCE 跑在以太网上就必须解决以太网“尽力而为”的丢包问题。PFC 负责在链路层面提供无损通道DCQCN 负责在端到端层面做拥塞控制。两者缺一不可。1.3 网络里的 PFC 和电源模块里的 PFC 别搞混这个坑我见得多了。一搜“PFC”搜出来一堆图腾柱 PFC、无桥 PFC、三相 PFC 电路全是功率因数校正Power Factor Correction的内容。这里要明确网络领域的 PFC 全称是 Priority Flow Control是 IEEE 802.1Qbb 标准作用是在以太网链路上按优先级做流控。它和电源电路里的功率因数校正完全是两码事只是在缩写上撞了车。如果你在调 RDMA 网络时去搜“PFC 电路”大概率会被带到电源设计那边去白白浪费半天时间。搜索时记得带上“数据中心”“无损网络”“802.1Qbb”这类限定词。2. 动手前先把服务等级、队列和缓冲池规划好2.1 用 802.1p 优先级把“无损”框出来以太网本质是尽力而为的要在上面实现不丢包需要给帧打优先级。IEEE 802.1Q 的 VLAN tag 里有 3 位 PCPPriority Code Point字段能表示 8 个优先级。我们从中选一个比如优先级 3作为无损优先级交换机为该优先级分配独立的队列和缓冲区。为什么要单独挑一个优先级而不是让所有流量都走无损因为 PFC 的作用机制是当某个优先级队列的缓冲区快满时交换机向对端发送 pause 帧让对方暂停发送该优先级的报文。如果 8 个优先级全开无损任何一条流拥塞都会暂停大量业务网络会被“头阻塞”拖垮。我建议的规划方式是选定一个固定的无损优先级例如 3全网统一。RoCE 流量打上 VLAN tag并把 PCP 设为 3。其他业务流量走普通优先级不受 PFC 影响。如果业务量很大可以再划分一个次要的无损优先级但不要超过两个否则内存资源和流控复杂度都会剧增。在华为 CE 交换机上无损队列通常会映射到硬件队列的某个编号你需要知道“PFC 优先级 3”最终落在哪个队列。不同型号和版本队列编号可能不同但基本都是按优先级从小到大映射到队列 0 到 7。2.2 ECN、CNP 和 DCQCN 的分工PFC 解决的是“链路瞬间突发导致丢包”的问题但它有个天然缺陷pause 帧会持续传播一旦拥塞扩散可能引发所有队列都暂停的死锁现象专业上叫 PFC 风暴。所以还需要端到端的拥塞控制机制这就是 DCQCN。DCQCN 借鉴了 QCN 和 DCTCP 的思路由三端配合工作交换机侧检测发送队列的长度当超过预设水线/阈值时对新到达报文打上 ECN 标记CE 标记。接收端收到带 ECN 标记的报文后生成 CNPCongestion Notification Packet拥塞通知报文回传给发送端。发送端收到 CNP 报文后按照 DCQCN 算法把发送速率降下来然后周期性尝试恢复最终收敛到一个接近链路容量又不丢包的速率。所以完整链路是 ECN 负责“标记拥塞”CNP 负责“上报拥塞”发送端的 DCQCN 算法负责“响应拥塞”。三者是一套协作体系。PFC 是兜底方案当 DCQCN 还没来得及降速时PFC 先把突发流量缓存下来避免直接丢包。2.3 Buffer 是这场戏的“水库”无损网络的效果优劣很大程度取决于交换机片上 buffer 的分配。PFC 给出的承诺是“不丢包”但前提是接收端要有足够的空间暂存突发的数据。这个空间就是 buffer 里的 headroom。我经常用一个水库的类比DCQCN 是上游的水库调度系统负责预测和削减洪峰PFC 是下游的堤坝加高防止瞬时洪水漫出来buffer 就是这段河道的容量。河道太窄堤坝再高也没用调度再准遇到极端流量高峰也需要缓冲。在华为 CE 交换机上配置无损队列时你通常需要给无损优先级分配足够的 buffer 空间特别是 headroom buffer。有些版本支持自动模式但我还是建议先手动配置一轮确保理解水线、alpha 因子和 headroom 的关系自动模式反而容易掩盖问题。3. 华为 CE 交换机的 DCQCN 和 PFC 配置记录3.1 开启 DCB/PFC华为 CE 交换机的配置命令在不同版本略有差异我这里给出的是较常见版本的配置思路具体请以你设备的操作手册为准。首先要进入 DCB数据中心桥接配置视图开启 PFC 功能并指定无损优先级。system-view dcb pfc priority 3这条命令表示把优先级 3 配置为 PFC 优先级。在某些版本里你还需要在接口下使能 PFC 能力interface 25GE1/0/1 priority-flow-control enable注意接口下的使能和全局配置缺一不可。我只在全局开了 PFC接口下没使能结果流量依然走普通队列RDMA 该丢包还是丢包。排查了半天才发现接口下需要单独放行。3.2 配置 ECN / DSCP 映射RoCE v2 的报文是 UDP 格式交换机要识别哪些报文属于无损优先级有两种做法根据 VLAN PCP 识别。根据 DSCP 字段识别。华为 CE 的做法通常是将 DSCP 映射到队列再让队列与 PFC 优先级关联。核心命令大致这样# 将 DSCP 值映射到本地优先级 dscp 46 cos 3RoCE v2 的 DSCP 值可以在网卡侧配置。我会在网卡侧把 RoCE 流量的 DSCP 设为 46这样交换机能识别到高优先级。然后为这个优先级队列开启 ECNqos bufferECN 的配置一般涉及队列门限值。华为 CE 的 ecn 配置大致是dcb ecn wred 3这部分不同版本差别比较大。如果你在设备上敲不下去多半是命令语义或视图不同先display dcb看当前支持的选项再对症下药。3.3 配置 QCN / DCQCN profile华为 CE 对 DCQCN 的支持是通过 QCNQuantized Congestion Notification模块实现的。全局启用后还要调整参数。常见可调参数包括 alpha、最小速率、最大速率等。qcn enable默认值通常是可用的但高性能场景下建议微调 alpha。alpha 影响交换机标记 ECN 的激进程度alpha 越小标记越激进发送端降速越早但吞吐可能偏保守alpha 越大标记越迟钝吞吐高但丢包风险也大。我的经验是从默认值开始先用 50% 背景流量压测看 ECN 标记比例再逐步调整。3.4 接口下使能无损队列和 buffer 调整接口下需要确保无损优先级使用的队列没有以默认丢包模式工作要把相关队列的调度和 buffer 调整为针对无损场景。命令大致涉及interface 100GE1/0/1 trust dscp qos queue 3 buffer headroom华为不同系列 CE 交换机的命令风格差异比较大。比如 CE6865 和 CE8861 的 QoS 配置方式就不太一样。最稳妥的办法是在设备上输入display this查看当前接口下已有的 QoS 配置确认没有冲突。这里分享一个我踩过的坑把优先级 3 作为无损队列后没有给队列调高调度权重结果无损优先级和普通优先级竞争带宽PFC 虽然没有丢包但 RoCE 流量的出端口带宽经常被普通流量抢占。后来配置了严格优先级调度把普通业务放在低优先级队列才解决带宽竞争问题。4. NVIDIA CX6 网卡端DCQCN 参数和 RoCE 模式配置4.1 安装驱动并确认网卡设备NVIDIA原 MellanoxCX6 网卡需要安装 MLNX_OFED 驱动推荐安装与网卡固件配套版本的驱动包。对于 ConnectX-6驱动通常包含在 MLNX_OFED 的最新 LTS 版本中。驱动装好后需要确认网卡在系统中被识别mst start mst status输出中会列出类似/dev/mst/mt4123_pciconf0这样的设备路径。后续mlxconfig就用这个路径操作。如果mst status看不到设备多半是驱动模块没有加载或者固件版本过老先去更新固件。4.2 用 mlxconfig 打开 RoCE 和 DCQCNCX6 网卡的 RoCE 模式、DCQCN 模式都通过mlxconfig来设置。核心参数如下mst start mlxconfig -d /dev/mst/mt4123_pciconf0 set LINK_TYPE_P1ETH mlxconfig -d /dev/mst/mt4123_pciconf0 set ROCE_MODE2 mlxconfig -d /dev/mst/mt4123_pciconf0 set DCQCN_MODE1 mlxconfig -d /dev/mst/mt4123_pciconf0 set ALPHA8 mlxconfig -d /dev/mst/mt4123_pciconf0 set RATE_LIMIT_MODE2各参数含义参数含义推荐值说明LINK_TYPE_P1端口链路类型ETH设置为以太网模式ROCE_MODERoCE 版本21 代表 RoCE v12 代表 RoCE v2DCQCN_MODE是否启用 DCQCN10 表示关闭1 表示打开ALPHA拥塞降速因子8值越大降速越平缓太小降速过猛RATE_LIMIT_MODE限速模式2配合 DCQCN 的速率恢复使用设置完成后需要重启网卡或 reboot 系统让配置生效。mlxconfig里改的是网卡 ROM 配置如果不重启驱动运行在旧参数下。4.3 网卡侧的 QoS 和优先级标签RoCE 流量默认不一定会打上 PCP 优先级标签。要让交换机识别无损优先级需要把 RoCE 流量的 DSCP 和 VLAN PCP 配置好。比较常见的做法是通过rdma-core和内核的 QoS 机制来实现。我常用的一种方式是用tc工具配合mqprio队列规则让 RoCE 流量自动落到指定优先级队列tc qdisc add dev enp130s0f0 root handle 1: mqprio num_tc 8 map 0 1 2 3 4 5 6 7 hw 1这里假设网卡支持硬件 QoS并且驱动把 VLAN 的 PCP 和队列对应起来。设置完成后用ip -details link show enp130s0f0来确认网卡支持的 QoS 能力。如果你用的是 RoCE v2还需要确认 UDP 的 DSCP 值。简单场景可以在 UDEV 规则或者网卡配置里把 RoCE 的 DSCP 设成与交换机匹配的值例如 46。两边对齐后ECN 才能正常工作。4.4 网卡状态确认配置完成并重启后通过以下命令确认 DCQCN 是否生效rdma link show输出中如果看到roce相关状态说明 RoCE 模式已启用。然后查看网卡统计确认没有异常丢包ethtool -S enp130s0f0 | grep -E cnp|ecn|pfc|drop如果 CNP 计数一直在涨说明 DCQCN 正在工作发送端在响应拥塞如果 PFC 计数暴涨到每秒几千几万说明链路频繁进入 pause 状态此时队列规划或 alpha 参数可能有问题。5. 验证方法不要只信“ping 得通”5.1 交换机侧看哪些计数器配置全部完成后最重要的事情是验证无损网络是否真的生效。先在交换机侧看 PFC 和 QCN 的相关统计display dcb pfc display qcn statistics重点关注PFC 帧计数是否持续增长。如果增长过快说明网络频繁触发流控可能 alpha 或 buffer 配置不合理。QCN/ECN 标记的报文数量。如果完全没有 ECN 标记说明 ECN 没有生效或者 DSCP 映射没有对齐。队列丢包计数。如果无损队列仍在丢包说明 headroom buffer 不足或水线太低。如果交换机侧这些计数有问题先在交换机侧排查不要急着去动网卡参数。5.2 网卡侧统计网卡侧的统计信息是判断端到端效果的关键。CX6 网卡的ethtool -S输出中和 RoCE 无损相关的计数器大致包括tx_vport_cnp/rx_vport_cnp发送和接收的拥塞通知报文数。tx_vport_ecn_marked/rx_vport_ecn_markedECN 标记报文数。rx_pcie_*PCIe 侧相关计数用于排除本地 PCIe 瓶颈。rx_dropped网卡层丢包这个数字必须为 0 或极低。我调测时的一个判断标准CNP 报文数量不应该持续暴涨。如果 CNP 每秒十几万个说明 DCQCN 响应异常。正常情况下CNP 只会在流量波动瞬间出现稳态下应该比较低。5.3 用 perftest 跑流的判断标准验证 RDMA 性能最直接的方法是使用 NVIDIA 官方提供的 perftest 工具。服务端ib_write_bw -d mlx5_0 -x 3 --report_gbits客户端ib_write_bw -d mlx5_0 -x 3 192.168.1.10 --report_gbits参数说明-d mlx5_0指定 RDMA 设备名。-x 3指定 GID 索引这里通常对应 RoCE v2。--report_gbits以 Gbps 为单位显示带宽。在 100Gbps 链路、未开无损配置时我跑出来的带宽只有 20~30Gbps延迟还不稳定配置好 PFC 和 DCQCN 后单流读写带宽能到 90Gbps 以上延迟波动明显减小。如果配置完成后带宽还是不理想优先检查交换机侧统计和网卡侧 CNP 计数。5.4 用背景流量模拟拥塞只跑单条 RDMA 流并不能充分验证无损能力因为流量太干净了。更靠谱的测试是叠加背景流量制造拥塞把被测网段打到接近瓶颈再观察RDMA 带宽是否还能维持在一个合理水平。PFC 和 ECN 计数是否正常增长而不是直接丢包。拥塞结束后RDMA 是否能在几毫秒内恢复速率而不是一直停在低速状态。我一般是这么测的用 iperf 起几条 TCP 背景流占满带宽然后同时跑ib_write_bw。如果 RDMA 带宽崩了说明 DCQCN 没有正确响应拥塞或者 PFC 优先级和普通业务优先级没有隔离干净。6. 实际部署中的几个坑和排查链路6.1 只开 PFC 不开 DCQCN 的后果这是最常见的错误。PFC 是无损网络的保底机制但它只负责“暂停发送”不能让发送端主动降速。如果只开 PFC 而不开 DCQCN遇到持续拥塞时交换机会不断向对端发送 pause 帧形成拥塞扩散甚至出现“PFC 风暴”最终整个网络吞吐跌到接近 0。业界有个说法叫“拥塞树”就是从一个端口拥塞扩散到整台交换机所有队列。排查思路如果你已经开了 PFC但没开 DCQCN跑高并发存储业务时整体吞吐反而低于无无损网络那基本就是 PFC 风暴。先确认网卡DCQCN_MODE1交换机 QCN 也使能两边都开了再谈性能。6.2 优先级约定不一致PFC 报文跑偏PFC 是按优先级暂停的。如果网卡发送的 RoCE 流量打的是优先级 3交换机配置的 PFC 优先级却是 4那流量就走错了队列被当成普通流量处理该丢包还丢包。端到端必须保证“网卡发送的优先级”等于“交换机识别的优先级”。排查思路在网卡侧把 RoCE 流量的 DSCP 或 PCP 打为固定值然后在交换机上看display dcb pfc中对应优先级的统计是否有增长。如果交换机上有接口收到了 pause 帧但管理接口上没有说明优先级匹配有问题。6.3 华为和 NVIDIA 参数命名差异同一套 DCQCN 算法华为叫 QCNNVIDIA 叫 DCQCN参数名称也不同。华为的 alpha 和 NVIDIA 的 ALPHA 虽然意思类似但取值范围和计算方式不一定完全对应。不要指望两边都填同一个值就一定最优一切以实测为准。我的做法先在两边都用默认参数跑基线再用背景流量压测根据 ECN 标记比例和带宽数据做单边调整。比如在 NVIDIA 网卡上调 ALPHA观察 ECN 标记比例和ib_write_bw的性能曲线。如果 ECN 标记比例高但带宽不低说明还有余量可以调大 ALPHA 提升吞吐如果丢包依然存在就要调小 ALPHA 并检查 headroom buffer。6.4 用 iperf TCP 流量代替 RDMA 测试的误导有人会用 iperf 来验证无损网络是否生效这是一个非常容易误判的操作。TCP 有自己的拥塞控制丢包后会自动降速表现上可能“看上去没问题”。但 RDMA 不存在类似的机制它依赖 DCQCN 来降速对拥塞的识别和响应完全不同。哪怕 TCP 跑满线速也不能证明 RDMA 就一定能跑满。所以验证 RDMA 必须用 RDMA 的测试工具比如 perftest 里的ib_write_bw、ib_read_lat。其他工具只能作为参考不能作为通过标准。6.5 业务优先级和 RoCE 共网时的隔离实际部署中RoCE 流量往往和存储、管理业务跑在同一张物理网络。如果所有业务都打同一个优先级PFC 暂停一个优先级就会影响所有业务这违背了无损网络的设计初衷。我的建议是RoCE 单独占用一个无损优先级存储控制流量和管理流量走其他优先级并且在交换机上对普通优先级队列设置合理的 WRED/丢弃策略。这样 RoCE 流量的 ECN 标记只作用于无损队列不会影响管理面的 SSH 或监控流量。6.6 DSCP 与 VLAN PCP 不一致导致 ECN 失效这是比较隐蔽的一个问题。RoCE v2 报文中有 DSCP 和 VLAN PCP 两个字段如果网卡发送的 DSCP 为 46而交换机 trust 的是 PCP两边没对齐ECN 标记和 PFC 识别就会各干各的无损网络等于虚设。排查思路确认交换机接口的模式是trust dscp还是trust dot1p再确认网卡设置的 DSCP 和 VLAN PCP 是否与交换机一致。两边必须使用同一个“识别语言”。如果让我给准备在 CX6 和 CE 上部署 RDMA 的朋友一条最实的建议先把无损优先级固定在同一个值比如 3网卡和交换机都指向这个优先级然后先测基线再逐步加 PFC、ECN、DCQCN。我从头到尾调了好几套环境最快的路径反而是一步步加、慢慢看别一次把参数全打满。配置完成后保存好网卡和交换机两侧的最终配置k标注好日期和测试结果。后面再遇到性能问题时回看这些记录定位速度会快很多。