首页 / 资讯中心 / 文章详情

数据中心网络传输新思路:接收端驱动与包级交织的实践解读

数据中心网络传输新思路:接收端驱动与包级交织的实践解读 ★ FEATURED ARTICLE
做数据中心网络的同行应该都清楚“数据包传输”这个词听起来基础真正把它做到极致却极其折磨人。最近我把 NSDI 2021 那篇《A New Approach to Datacenter Packet Transport》的论文又完整啃了一遍结合我们自己在实验环境里折腾拥塞控制、负载均衡和智能网卡的经验整理出这份阅读笔记。这篇笔记不是按论文章节逐页复述而是把它的动机、核心设计、实验结论以及我个人认为对工程实践有启发的地方串起来。如果你正在做数据中心网络协议、RDMA 调优或者想搞清楚接收端驱动、无状态转发这类新思路到底靠不靠谱这篇笔记应该能给你一些参考。1. 论文在解决什么问题数据中心传输的三大痛点1.1 数据中心流量不是“单一的流”而是长短杂居的混行交通很多人一想到数据中心网络脑子里浮现的是一个持续灌满带宽的大水管。真实场景完全不是这样。数据中心内部流量是典型的“长短杂居”Web 搜索、推荐请求这类短流可能只有几十 KB却要求毫秒级甚至亚毫秒级完成机器学习训练、数据备份这类长流动辄几百 MB 甚至 GB 级需要长时间稳定占用带宽。更麻烦的是 incast 场景成千上万个分区同时向一个节点回包瞬间把交换机端口队列打爆。这种混合流量对传输层的要求极其矛盾短流希望队列越短越好最好永远不排队长流希望队列有一定深度才能充分吸收突发、保持高利用率。传统传输机制处理这种矛盾的方式通常很粗暴——要么牺牲短流延迟要么牺牲长流吞吐很难两头兼顾。论文开篇就是在强调这个问题如果传输机制本身不能感知流量形态并通过调度去协调那无论链路带宽翻多少倍用户体验都不会有质变。1.2 传统传输机制的三个结构性矛盾第一个矛盾是端到端反馈滞后。传统 TCP 靠丢包判断拥塞丢包本身意味着队列已经溢出反应天然慢半拍DCTCP 这类改进方案用 ECN 标记做早期反馈比丢包好一些但 ECN 阈值非常敏感阈值调大了队列照样堆积调小了带宽利用率骤降实际运维里调参调到头大。第二个矛盾是负载均衡的粒度太粗。ECMP 按五元组哈希把一个流固定到某条路径上问题在于流的大小差异悬殊两条长流哈希到同一路径立刻就把链路塞满而旁边一条空闲路径却完全用不上。虽然 flowlet 方案可以根据空闲间隙把流切碎后重新哈希但间隙太短容易导致频繁乱序间隙太长又失去了切流的意义工程上很尴尬。第三个矛盾是交换机缓存相对链路速率严重缩水。链路速率从 10G 涨到 100G、400G交换机缓存并没有等比例增长。缓存越小突发流量下队列越容易溢出而传输层却不能快速响应。这些矛盾叠加在一起让数据中心传输层的设计变成了一场围绕“队列长度”的攻防战。1.3 论文的定位不是修补而是把传输控制整体翻转这篇论文提出的新方法不是对 TCP 或者 DCTCP 打补丁而是完全换了一套设计范式它把传输控制的“大脑”从发送端搬到接收端让交换机从“有状态转发”变成“无状态转发”同时用数据包级的路径交织替代流级负载均衡。一句话概括就是让网络设备和接收端协作把路径选择和拥塞控制做成一个闭环而不是让发送端闭着眼睛猜。这也是为什么论文标题敢用“A New Approach新方法”这种说法。它赌的是未来数据中心端点处理能力足够强完全可以支撑接收端做更多计算也赌可编程交换机和智能网卡会普及让网络设备有能力提供细粒度的拥塞反馈。这两点恰好是过去十年数据中心硬件演进的真实方向也是我觉得这篇论文值得仔细读的核心原因它不是在想象一个空中楼阁而是在顺着硬件能力边界重新设计传输协议。2. 核心设计思路解读一次“控制权转移”2.1 为什么传输控制要交给接收端传统传输的核心动作是发送端维护拥塞窗口根据 ACK、丢包或者 ECN 信号调节发送速率。这种设计的隐含假设是“发送端知识最多”但真实情况恰恰相反发送端离网络最远它对路径上发生了什么几乎一无所知只能通过间接信号推测。接收端就不一样。接收端能看到包到达的顺序、速率的波动、有没有缺口甚至能根据接收速率直接估算当前可用带宽。把调度决策放在接收端相当于让最接近现场的人做调度指挥而不是让远端的人隔空猜。类比一下传统方式像物流总部基于司机回报的“大概堵车”来规划路线接收端驱动则像仓库现场看到货品到货节奏后直接告诉司机“现在走哪条路”。哪个反应快、哪个更准不言而喻。具体到机制上接收端会为每条流维护一个预期的包序号窗口持续跟踪实际到达进度。一旦发现到达速率低于预期或者收到交换机反馈的拥塞信号就调整后续的发送计划把这个计划封装在反馈报文里发给发送端。反馈报文的频率不是每包一次而是根据链路状态动态调整避免控制开销反噬带宽。2.2 无状态数据平面让交换机做“哑巴”但不笨论文对网络设备的要求特别有意思交换机不需要维护任何连接状态不需要记录每条流当前走到哪了只需要做两件事。第一根据包头信息和全局路径权重选择一个合适的下一跳第二根据本地队列的即时忙闲状态在包头一个固定字段上打一个拥塞标记。为什么坚持无状态因为数据中心网络里的并发流数量太恐怖一台核心交换机上同时有几百万条流是常态。任何需要为每条流维护状态的方案都会面临三座大山状态表存不下、查表耗延迟、表项老化导致逻辑复杂。而无状态交换机的处理逻辑简单、容量高、一致性好成本优势明显。关键在于无状态不代表无智能。交换机虽然不认流但它可以利用队列占用率这个本地信息做宏观决策队列短就多往这条路径送包队列长就少送。这相当于每个交换机都在做“局部均衡”配合接收端的全局调度两边各司其职。2.3 包级路径交织把每个包当成独立调度单元传统流级负载均衡把整条流绑死在一条路径上问题前面说过了。flowlet 把流切成小块但切块时机不好把握。这篇论文直接上包级交织同一个流的不同数据包完全可以根据当前各路径的实时状态选择不同路径到达接收端。包级交织的好处非常直观调度粒度最细能把每一条可以用的链路都填满无论流大小都能享受全网络带宽。代价也很明显——同一个流的包会乱序到达如果按传统协议栈的处理逻辑这几乎等于灾难。但论文做了一个关键取舍我不会试图在发送端避免乱序而是主动接受乱序把重排序逻辑全部放到接收端。数据中心内部链路延迟差异通常只有微秒级RTT 差异很小因此乱序窗口可控。配合接收端较强的处理能力重排缓冲的开销是完全可以接受的。这个取舍看似大胆其实很务实既然硬件条件已经允许接收端做更多事就没必要为了简化接收端而让发送端承担所有复杂性。3. 机制细节与工程实现要点3.1 数据面转发与路径选择编排先看数据平面如何工作。发送端启动一个流时会在报文头部携带流标识和一个初始路径标识。接入交换机收到报文后不是查五元组表而是根据“路径权重 实时队列状态”做决策。路径权重可以通过控制平面定期下发也可以用数据平面的探测机制自动调整实时队列状态则由交换机的队列深度寄存器直接读出。这里我补一段简化版的逻辑示意方便理解这种“无状态但聪明”的转发到底怎么落地on packet ingress: if packet.is_control(): # 控制报文走固定高优先级队列 nexthop control_path() else: # 数据报文根据当前各出端口队列占用率选择路径 for port in available_egress_ports: weight base_weight[port] - queue_depth[port] * k nexthop select_weighted(weight_list, packet.flow_id) # 标记拥塞等级0空闲1忙碌2拥塞 mark quantize(queue_depth, threshold_1, threshold_2) rewrite_packet_field(packet.congestion_mark, mark) forward(nexthop)上面的 k 是路径权重对队列深度的敏感系数阈值和 k 的取值对性能影响很大。论文实验里这些参数不需要针对每条流动态调整固定值就能有不错表现。这一点非常重要因为可调参数越少越容易在生产环境落地。3.2 接收端调度真正的“大脑”在哪里接收端是整套机制的调度核心。它要做的事包括重排乱序包、识别缺口、估算可用带宽、生成反馈报文。重排逻辑不是简单地把乱序包塞进缓冲区等序列号连上而是要结合“预期速率”做预判。比如说接收端发现 100 到 200 号包还没到但 201 到 300 号已经到了它会先判断这不是拥塞导致的减速因为短时间内的突发乱序可能只是路径差异如果缺口持续超过一个阈值比如一个 RTT 或者若干包间隔它才认定是拥塞或丢包进而主动干预。带宽估算采用滑动窗口统计记录最近若干微秒内收到的有效数据量除以时间窗口就得到当前实际吞吐。这个值会与发送端的目标速率做比较差值转换为反馈报文里的建议速率调整量。反馈报文不是每个数据包都回而是累积若干信息后批量发送否则控制平面会挤占数据平面的带宽。这个批量反馈的设计本质上是在控制精度和带宽开销之间做折中。3.3 发送端从“满脑子状态”的决策者变成“听指挥”的执行者传统 TCP 发送端维护的拥塞窗口、慢启动阈值、RTT 估计器、重传计时器在新方案里大幅简化。发送端不再自己猜测网络状况而是从接收端反馈中拿到明确的“下一阶段发送速率”和“需要重传的包序号”。它要做的事情只剩两件按接收端指定速率做发送门控以及按接收端指明的缺口做精准重传。这个简化带来一个工程上极其重要的红利发送端 CPU 开销大幅下降。线速 100G 下传统 TCP 为了维护每流状态需要耗费大量 CPU 周期新方案把这些负担推给接收端而接收端本身就可以用 DPU、可编程网卡这种专门硬件去处理从而让 CPU 专注于业务。对于云厂商来说这意味着同样一台服务器可以承载更多租户流量是实打实的成本收益。为什么重传也会更快因为接收端主动上报缺口发送端不需要傻等超时定时器。传统 TCP 遇到丢包往往要等一个 RTO尤其在长肥网络中动辄几十毫秒新方案里接收端一旦判断缺口是丢包立刻随反馈报文告诉发送端“你把这几号包重发一下”时间被压缩到接近网络延迟量级。3.4 与主流方案的对比为了把新方案的取舍讲清楚我整理了一个对比表覆盖控制位置、网络需求、重传触发和负载均衡粒度这几个关键维度方案控制位置网络设备要求重传触发负载均衡粒度DCTCP发送端交换机支持 ECN 标记发送端超时/ACK 检测流级 ECMPHoma接收端需要交换机支持优先级队列接收端检测缺口流级路由本文方案接收端可编程交换机无状态转发标记接收端反馈缺口数据包级交织能看出来新方案在负载均衡粒度上走得更激进但对网络设备提出了明确的要求必须支持可编程的转发逻辑能修改包头标记。好在 2021 年之后可编程交换机和 DPU 已经开始进入主流数据中心这不再是不切实际的硬件假设。4. 实验评估解读从模拟器到真实测试床4.1 实验环境怎么搭的论文先在大规模模拟器环境做验证搭建了一个超过百节点的 Clos 拓扑链路速率设置从 10G 到 100G 混合交换机缓存设置成远小于带宽时延积模拟真实硬件受限的情况。流量负载采用多种生产环境常见的模型包括 Web 搜索的短流模型、数据挖掘的长流模型以及高并发的 incast 模组。这种“缓存远小于 BDP”的设置让我印象很深因为很多传输方案在实验里配了很大的缓存看着性能很好一到真实交换机上就露馅。论文把缓存设得很小相当于主动给自己上难度也让结论的可信度更高。在真实测试床部分论文使用了带可编程数据面的设备搭建了小规模集群规模不大但足够验证功能的正确性。我的经验是模拟和测试床之间的差距往往来自细节硬件里队列深度不是线性变化的包头修改也不是零成本的。论文在测试床部分专门讨论了这类差异并且给出了和模拟趋势一致的结论这一点值得学习。4.2 关键指标与结果评估维度集中在平均完成时间、长流吞吐、incast 场景稳定性和尾延迟。短流在大多数场景下表现接近理想值平均完成时间比 DCTCP 降低一个量级99% 尾延迟也明显收窄。原因很容易理解短流的包被分散到多条路径上同时接收端调度避免了不必要的重传等待队列堆积又被无状态转发和拥塞反馈压住这几重因素叠加自然把延迟拉下来。长流吞吐作为另一个硬指标结果显示链路利用率保持在较高水平没有因为包级交织出现明显的乱序重传浪费。incast 场景下因为交换机反馈和接收端调度的配合没有出现传统 TCP 的吞吐坍塌现象。相比之下传统方案在 incast 并发达到一定程度时吞吐会突然掉到极低点这一直是数据中心传输的老大难问题。4.3 我读实验部分时格外关注的三个细节第一交换机缓存压力大幅下降。因为大多数拥塞事件在网络侧就被标记接收端也会主动调速交换机队列长度被控制在很浅的位置。这正好应对了“带宽增长但缓存不增长”的现实。第二对时间同步的要求不高。接收端判断缺口用到的 RTT 测量基于本地时钟即可完成不需要全网严格时间同步。这大大降低了部署门槛因为机房哪怕有几百台设备时间同步本身也是个不小的工程负担。第三端到端升级成本不小。这套方案需要同时改造交换机数据面和端点网络栈如果只在某一侧做修改兼容性会比较有限。论文没有回避这一点这也是它在实际环境中落地最大的门槛。5. 对实际工程的启发与避坑心得5.1 它适合哪种部署环境如果你所在的团队还没有可编程交换机或 DPU我并不建议立刻把现有 TCP 栈换成这套方案。先在上层网络模拟器里跑通自己的流量模型确认瓶颈确实在传输层再考虑硬件升级的投入。如果你已经在部署可编程交换机和智能网卡那么这套思路和现有硬件能力是天然对位的。可以先把数据平面的无状态转发和拥塞标记做出来端点侧先用普通服务器验证功能再逐步把接收端调度逻辑下放到 DPU。和 RoCEv2 这类 RDMA 协议的融合也值得提前规划RoCE 的优先级流控和这套方案的拥塞标记可以在同一套队列体系中共存但配置上要特别注意优先级队列不要喧宾夺主。5.2 迁移过程中容易踩的坑第一个坑以为接收端驱动就不需要拥塞控制。真实情况恰恰相反接收端反馈的及时性是这套方案的关键反馈频率太低发送端就成了无头苍蝇反馈频率太高控制报文会吃掉大量带宽。这个频率一定要根据实际链路容量做自适应不能图省事配一个固定值。第二个坑包级乱序对接收端内存和 CPU 的压力被严重低估。我曾经在测试中发现当网络负载均衡做得太“平均”时包到达顺序反而更加分散接收端需要同时维护的乱序窗口变得很大。如果接收端网卡没有足够缓存批处理能力性能会急剧退化。解决办法是限制同一时刻在途的最大包数量宁可牺牲一点路径利用率也要控制重排窗口的规模。第三个坑调试手段的缺失。传统 TCP 有非常成熟的工具链ss、tcpdump、窗口打点出了问题很容易定位。这类自定义传输没有系统级统一观测接口连“当前发送速率是多少”这种基础问题都要自己打点才能回答。做这套方案之前先规划好遥测和监控系统否则上线后出了性能问题会排查到怀疑人生。5.3 复现过程中纠正的几个错误认知读这篇论文之前我一度认为“包级负载均衡 疯狂乱序 不可用”读了之后心态完全变了。只要重排逻辑放在接收端且接收端有足够的处理能力乱序是从“灾难”变成了“可控成本”。这个认识上的转变直接影响了我对很多网络方案的态度。另一个错误认知是我习惯用 ECN 阈值越低越好的思维去套新方案。传统 DCTCP 里 ECN 阈值决定了反馈灵敏度阈值设太高会让队列堆积。但在这套方案里交换机标记只是接收端调度的一个信号接收端还会结合到达速率和缺口做综合判断因此对标记阈值的敏感性远低于 DCTCP。用旧经验硬套新模型很容易得出错误结论。最后一点是这套方案虽然名为“新方法”但它并没有推翻 TCP 时代积累的很多洞察拥塞信号要早于丢包发现、重传要尽量不等超时、负载均衡要尽量细粒度。它做的是把之前做不到的工程假设接收端更强、网络可编程变成设计前提从而把旧理想变成可实现的东西。想真正理解论文价值不妨从这个角度切入而不是死记某些算法参数。我个人在整个阅读和试验过程中的体会是传输协议设计的关键问题从来不是“哪种算法更先进”而是“状态到底该放在哪里”。把状态放在发送端简单但盲目把状态放在网络里精确但昂贵把状态放在接收端兼顾了准确和可扩展。这篇论文最值得借鉴的不是具体的包格式或阈值选择而是这种寻找“状态正确归宿”的思维。如果你也在做传输相关的工作建议先把自家流量特征量清楚再看哪些痛点真正出在传输层然后再谈引入这种新体系是否值得。
阅读完成 · 觉得有帮助?
咨询建站