尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

DRL-Routing:基于深度强化学习的SDN智能路由算法解析与复现

发布时间:2026/9/24 5:36:18

资讯中心
01
ARTICLE

DRL-Routing:基于深度强化学习的SDN智能路由算法解析与复现

DRL-Routing:基于深度强化学习的SDN智能路由算法解析与复现
简介《一种基于深度强化学习的SDN路由算法》是一篇面向网络工程与机器学习研究者的学术论文PDF聚焦深度强化学习在软件定义网络流量工程中的应用。该资源仅含1个PDF文件包体大小1.36MB收录论文完整内容。论文提出DRL-Routing算法使用较全面的网络信息作为状态表示采用一对多的网络配置进行路由选择并通过奖励函数调整往返路径的吞吐量实验显示相比传统的OSPF算法与最小负载路由算法该算法能获得更高的奖励经适当训练后可让各交换机之间习得更优的路由策略从而增大网络吞吐量、降低网络延迟与数据丢包率。该文档包含算法架构、关键公式、仿真结果以及网络监控模块和动作转换器的功能说明适合作为深度学习、软件定义网络方向的研究参考文献也可为相关科研课题设计提供理论支撑。目前已有651人学习下载可供相关专业人员参考。1. 这篇 DRL-Routing 论文解决的是 SDN 里最头疼的流量工程问题深度强化学习路由算法在软件定义网络SDN里不是新鲜概念但大多数论文只给一个框架图参数和实现细节全靠猜。这篇 2021 年发表在《上海师范大学学报自然科学版》的论文给出了一个完整的 DRL-Routing 算法闭环状态用 8 类网络信息表示动作是一对多的路径配置奖励函数可以分别调整往返双向的吞吐率权重。更实在的是它附带了 Fat-tree、NSFNet、ARPANet 三种拓扑上的完整对比数据明确告诉你 Dt1 s 时效果最好。对于正在做 SDN 控制器选型、或者在 Ryu 上写路由模块的同学这份资料可以直接当需求规格书用不需要再从零设计 MDP 建模。2. 为什么 OSPF 和 LL 在动态流量下不行先看懂算法要解决的问题2.1 传统路由的贪婪本质OSPF 的核心是 Dijkstra 最短路权重通常是静态的链路开销LLLeast Loaded虽然会挑当前负载最小的链路但它只看到局部时刻的负载没有对未来流量做任何预测。论文里给的对比数据很能说明问题在 NSFNet 拓扑上传输 40 GB 文件OSPF 需要 56.70 sLL 需要 48.00 s而 DRL-Routing 只要 22.68 s。差距不是百分之几是两倍以上。原因在于这类贪婪算法在流量不断变化时容易被瞬时拥塞带偏。OSPF 一旦算出路就长时间不变流量高峰来了只能硬扛LL 虽然动态调整但每个交换机各自为政没有全局视角很容易出现大家都躲开 A 链路、结果 B 链路又堵了的踩踏效应。我在真实环境里见过类似问题——某个教育网核心节点OSPF 的 cost 值好几年没调过视频流量一上来就丢包后来改成周期性重算才缓解。2.2 SDN 给了什么新机会SDN 控制器掌握全网视图这是传统分布式路由协议做不到的。论文的 DRL-Routing 利用了三点控制器可以集中采集所有链路的状态吞吐量、延迟、端口速率控制器能通过 OpenFlow 消息批量改写流表控制器的应用层可以跑强化学习智能体把路由决策变成状态到动作的映射。这套思路本质上把网络变成了一个可编程的强化学习环境。传统路由协议里链路权重是手工配的在 DRL-Routing 里权重是智能体通过试错学出来的。论文中智能体与环境的交互元组是 St、At、St1、Rt1也就是在状态 St 下执行动作 At环境反馈奖励 Rt1 并转移状态循环直至累积奖励最大。这个建模方式和 OpenAI Gym 的交互模式完全一致意味着你可以在仿真环境里训练好策略再部署到真实控制器。2.3 强化学习选型为什么是 DQN 家族而不是策略梯度论文用的是带优先级抽样的竞争型网络架构Dueling DQN Prioritized Experience Replay。这个选择很符合 SDN 路由场景路由动作空间是离散的路径集合Dueling 网络把 Q 值分解成状态价值和动作优势两部分在路由此类不同动作之间优势差异不大但状态价值变化明显的场景里比普通 DQN 收敛更稳。优先级抽样解决的是路由样本中拥塞样本少但信息量大的不平衡问题。相比之下PPO 这类策略梯度算法在动作空间连续时优势明显但路由路径本质上是离散的强行用连续输出再映射回路径反而增加了实现复杂度。3. DRL-Routing 核心设计拆解状态、动作、奖励函数的可复现代码3.1 状态向量的 8 个分量怎么算论文定义状态集 S [f1, f2, ..., f8]这 8 个分量的计算方式是整个算法能否收敛的关键。我按论文公式整理成一份可直接落地的状态采集逻辑def compute_state(links, switch_stats, delta_t): state [] # f1: 链路容量率当前带宽 / 最大带宽 f1 {link.id: link.current_bandwidth / link.max_bandwidth for link in links} # f2: 链路吞吐率delta_t 内发送的数据量 / (带宽 * delta_t) f2 {} for link in links: data_sent switch_stats[link.src][link.dst].tx_bytes_delta f2[link.id] data_sent / (link.max_bandwidth * delta_t) # f3: 链路延迟RTT 或 LLDP 探测结果 f3 {link.id: link.latency for link in links} # f4: 链路状态值工作为 1否则 0 f4 {link.id: 1 if link.is_up else 0 for link in links} # f5: 链路信任级别初始中值 0.5异常时下调 f5 {link.id: link.trust_level for link in links} # f6/f7: 往返链路上交换机的平均吞吐率 f6 compute_avg_throughput(switch_stats, directionuplink) f7 compute_avg_throughput(switch_stats, directiondownlink) # f8: 经过交换机的概率集由路径计算模块提供 f8 compute_path_probability(links) return [f1, f2, f3, f4, f5, f6, f7, f8]这里有几个容易踩坑的点。f2 的分母是带宽乘以 delta_t如果你把 delta_t 的单位搞错秒和毫秒混用吞吐率会差三个数量级奖励函数直接失效。f5 信任级别论文里只说设置为中值没给更新公式我这边的做法是连续两次探测失败的链路信任值减 0.1下限 0.1恢复后每次加 0.05上限 1.0。f8 是路径经过某交换机的概率这个需要和下面的动作生成模块配合不是独立计算的。归一化很重要。f1 和 f2 天然在 0 到 1 之间但 f3 延迟的数值范围可能是几十微秒到几百毫秒不归一会导致 DQN 的状态输入量纲差异过大训练时 loss 波动剧烈。我习惯把延迟也做 min-max 归一化# 延迟归一化min_latency 和 max_latency 取历史统计值 f3_normalized {link.id: (link.latency - min_latency) / (max_latency - min_latency)}3.2 动作为什么是一对多控制器可伸缩性的关键动作集定义 A {ai}其中 ai 是源交换机到所有目标交换机及其反向路径的集合。这里一对多的意思是智能体每次决策不是只算一条路径而是同时为所有目的交换机选路。这么设计的原因很直接——如果每个流都让智能体算一次控制器在大规模网络下会成为瓶颈。我理解这个设计的工程价值在于它把逐流的细粒度调度变成了周期性的全局路径重配置。每隔 delta_t 时间智能体根据当前全网状态一次性更新所有交换机的流表这与实际 SDN 控制器的流表下发方式更契合。论文中没有给出 PDA 函数的具体代码但意思应该是调用路径发现函数基于当前拓扑为源节点枚举所有可行路径。我用一个简化版来说明def pda_build_action_space(topology, src_switch): 构造动作空间src 到所有 dst 的路径组合 action_space [] dst_switches [s for s in topology.switches if s ! src_switch] # 用 k-shortest paths 预生成候选路径避免动作空间爆炸 path_options {} for dst in dst_switches: paths k_shortest_paths(topology, src_switch, dst, k3) path_options[dst] paths # 动作 为每个 dst 选择一条路径的组合 # 注意这里做了剪枝实际组合数 k^len(dst_switches)需要限制规模 for combination in itertools.product(*path_options.values()): action_space.append(combination) return action_space这段代码有个隐含问题如果网络有 10 个目标交换机每个目标 3 条候选路径组合数是 3 的 10 次方约 59049 个动作。DQN 输出层有 5 万个节点还能接受但如果你用冗余拓扑让每个目标有 10 条路径动作数直接到 100 亿训练根本跑不动。所以我的实际建议是动作空间构建时用拓扑剪枝优先保留链路信任级别高、延迟低于阈值的路径把候选路径数压到每个目标 3 条以内。3.3 奖励函数往返双向吞吐率怎么加权奖励函数设计是这篇论文最值得抄的地方。r r1 r2其中 r1 是吞吐率奖励r2 是延迟奖励。r1 φ × r_u1 (1 - φ) × r_d1r_u1 是源到目的的吞吐率r_d1 是目的到源的吞吐率φ 是影响因子。这个设计高明之处在于它显式建模了往返路径而不是只优化单向流量。对于 TCP 流量确认包走的是反向路径如果反向路径拥塞发送端吞吐率同样上不去。我做过类似实验只优化正向路径时TCP 的 ACK 在反向路径排队整体吞吐率反而下降双向优化后才真正提上去。我建议在实现时把 r2 定义得更具体一些用归一化延迟来写def compute_reward(state, action, phi0.6): # 吞吐率部分往返双向 throughput_uplink state.f6[action.src] # 源到目的方向 throughput_downlink state.f7[action.src] # 目的到源方向 r1 phi * throughput_uplink (1 - phi) * throughput_downlink # 延迟部分动作路径上的平均延迟越小越好 path_latency action.paths_latency # 所有路径的延迟总和 r2 1.0 / (1.0 path_latency) # 归一化到 (0, 1] return r1 r2φ 的取值值得多跑几轮实验。φ1 时智能体只关心上行吞吐率对下行流量视而不见φ0.5 时双向兼顾适合对称业务如果网络里主要是下载类业务视频、文件传输φ 取 0.7 到 0.8 会让上行奖励权重更大一些。论文在实验里得出的结论是 Dt1 s 时效果最好这也侧面说明奖励计算的时间窗口不能太长——窗口太长状态变化被平均掉智能体感知不到瞬时的拥塞波动。4. 仿真实验复现步骤Mininet Ryu DRL 智能体的完整闭环4.1 环境搭建和拓扑生成论文实验用的是 Mininet 建虚拟网络、Ryu 做 OpenFlow 控制器、Iperf 生成流量。这个组合我认为非常合理Mininet 轻量Ryu 的 REST API 和事件机制成熟Iperf 能精确控制流量速率。复现时我建议用下面的环境组合# 安装依赖Ubuntu 20.04 验证过 sudo apt install mininet iperf3 python3-pip pip install ryu os-ken # os-ken 是 Ryu 的活跃维护分支API 兼容拓扑我用的是 NSFNet 的 14 节点拓扑因为它比 Fat-tree 更有代表性——Fat-tree 对称性太强算法容易钻空子NSFNet 的不规则拓扑更接近真实骨干网。Mininet 里创建 NSFNet 拓扑的脚本from mininet.topo import Topo class NSFNetTopo(Topo): def build(self): # NSFNet 骨干节点按论文图结构映射 switches [s1,s2,s3,s4,s5,s6,s7, s8,s9,s10,s11,s12,s13,s14] for sw in switches: self.addSwitch(sw) # 论文中的 NSFNet 链路带宽统一 10Mbps edges [(s1,s2),(s1,s3),(s2,s3),(s2,s4), (s3,s4),(s4,s5),(s4,s10),(s5,s6), (s5,s9),(s6,s7),(s6,s8),(s7,s8), (s8,s9),(s9,s10),(s10,s11),(s10,s14), (s11,s12),(s12,s13),(s13,s14)] for src, dst in edges: self.addLink(src, dst, bw10, delay5ms)关键在于链路的 bw 和 delay 参数。论文没给具体的链路带宽我建议统一 10 Mbps、5 ms 延迟这样 Iperf 打流的时候拥塞现象明显算法优劣能拉开差距。如果你链路配成 1 Gbps普通流量根本打不满DRL 和 OSPF 的差异就显示不出来了。4.2 Ryu 控制器里跑 DRL 智能体的骨架Ryu 侧的逻辑分为两块网络监控模块和动作执行模块。下面是一个最简骨架from ryu.base import app_manager from ryu.controller.handler import set_ev_cls, CONFIG_DISPATCHER from ryu.controller import ofp_event from ryu.lib.packet import packet class DRLRoutingApp(app_manager.RyuApp): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.agent DRLRoutingAgent() # 深度强化学习智能体 self.network_monitor NetworkMonitor() # NMM 模块 self.action_translator ActionTranslator() # ATM 模块 self.datapaths {} self.delta_t 1 # 状态采样周期单位秒 set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): datapath ev.msg.datapath self.datapaths[datapath.id] datapath def periodic_train_and_route(self): # 1. 用 NMM 采集链路状态 state self.network_monitor.collect_state() # 2. 智能体根据状态选动作 action self.agent.select_action(state) # 3. 动作转换器把路径转为 OpenFlow 流表 flows self.action_translator.action_to_flows(action) # 4. 下发流表到交换机 self.install_flows(flows) # 5. 下一个定时周期继续 self.loop.call_later(self.delta_t, self.periodic_train_and_route)这段代码有几个我实际遇到的问题。首先要重点说明Ryu 的事件循环不是多线程的如果你在 agent.select_action 里跑神经网络前向推理耗时过长会阻塞 Ryu 处理 OpenFlow 协议消息表现为交换机掉线或 LLDP 探测超时。我通常把推理和流表下发解耦或者用线程池运行推理。其次动作转换器下发流表时要优先删除旧路径上交换机中的冗余流表项——论文里明确提到由路径上最后一台交换机将 OpenFlow 消息发送到第一台交换机删除旧路径在交换机中的相应规则。这个删除顺序不能反否则在更新的中间状态会出现路由黑洞。4.3 DRL 智能体训练循环优先级抽样的 Dueling DQN算法主体我建议直接用 Dueling DQN Prioritized Replay 的标准实现网络结构可以照着论文图 2 的步骤来import numpy as np import torch import torch.nn as nn class DuelingDQN(nn.Module): def __init__(self, state_dim, action_dim): super().__init__() self.feature nn.Sequential( nn.Linear(state_dim, 128), nn.ReLU(), nn.Linear(128, 128), nn.ReLU() ) # Dueling 结构价值和优势分离 self.value nn.Linear(128, 1) self.advantage nn.Linear(128, action_dim) def forward(self, x): features self.feature(x) value self.value(features) advantage self.advantage(features) # 优势均值化保证可辨识性 q_value value advantage - advantage.mean(dim1, keepdimTrue) return q_value # 训练时用优先级抽样TD 误差大的样本被抽中的概率更高 class PrioritizedReplayBuffer: def __init__(self, capacity, alpha0.6, beta0.4): self.capacity capacity self.alpha alpha # 优先级指数 self.beta beta # 重要性采样权重 self.buffer [] self.priorities np.zeros(capacity)网络结构不是我原创参考的是论文引用的 Dueling Network 架构文献。实际跑训练时状态维度是 8 类特征展平后的长度动作维度是 PDA 函数生成的路径组合数量。我发现在 NSFNet 这种 14 节点的拓扑上经过路径剪枝后动作维度大约在 200 到 400 之间网络中间层 128 就够了再宽容易过拟合到训练流量模式。训练时每轮让智能体在拓扑里跑 100 个回合每个回合时长 200 秒左右大约 3000 步时能观察到奖励曲线明显上升。4.4 用 Iperf 打流验证流量模式怎么设置才有区分度训练和评估时的流量生成是关键。如果只开一条 Iperf 流网络根本没有拥塞算法优劣看不出区别。我建议至少起 3 到 5 条 Iperf 流让部分链路出现拥塞。论文用的是 Iperf 生成流量我建议用 iperf3 的并行流模式# 从 h1 到 h14 打 3 条并行 TCP 流每条 2 Mbps打 30 秒 iperf3 -c 10.0.0.14 -p 5201 -t 30 -P 3 -b 2M # 另开一个终端从 h5 到 h10 打 UDP 流制造拥塞 iperf3 -c 10.0.0.10 -p 5202 -u -b 5M -t 30需要注意 UDP 流和 TCP 流同时存在时UDP 会把 TCP 的带宽挤掉这其实是模拟了真实网络中视频流量和文件传输并存的情况。拥塞链路上 RTT 会增大TCP 发送窗口收缩吞吐率下降这时 DRL-Routing 会试图把流量重新分布到空闲链路。5. 避坑与调参复现 DRL-Routing 路上的 4 个常见问题5.1 奖励不收敛一直在低位震荡现象训练几千步后奖励曲线没有上升趋势一直在 0.5 附近波动。 原因奖励函数里的 r2延迟项和 r1吞吐率项数值不在同一个量级。r1 是吞吐率可能在 0 到 10 之间r2 如果直接用延迟的倒数可能只有 0.001 到 0.01。结果是智能体只优化 r1对延迟完全无感。这个问题的根源是论文没有给出 r2 的具体归一化公式。 解决把 r2 改成归一化延迟奖励如 1 / (1 path_latency) 或使用负的延迟对数。确保 r1 和 r2 的量级一致系数可以后期统一缩放。5.2 动作空间爆炸导致训练内存溢出现象在 14 节点拓扑上跑PDA 函数生成动作集时内存占用飙升程序崩溃。 原因所有源到所有目标的路径组合是指数级增长的。论文没提剪枝细节但你必须在实现时加约束。 解决路径候选数限制为 k3并且按链路信任级别和延迟做初筛。如果目的节点和源节点之间本身只有一条物理路径就不要枚举动作固定为那条。一个实用做法是先用 NetworkX 的 k_shortest_simple_paths 预生成候选再过滤掉延迟过长的路径最后才构建组合。5.3 Mininet 里 Ryu 控制器频繁触发 PacketIn 事件CPU 被打满现象拓扑跑起来后 Ryu 进程 CPU 占用率 100%智能体推理明显卡顿。 原因OpenFlow 默认的 flow_mod 安装有延迟交换机在没有匹配流表项时会发送 PacketIn 给控制器控制器处理不过来。 解决在交换机配置里设置 idle_timeout 和 hard_timeout同时用默认流表项匹配所有未匹配流量避免每个包都触发 PacketIn。另外训练时把开关的探测间隔调大不要用默认的 LLDP 每 1 秒探测一次改为 3 到 5 秒。5.4 Dt1 s 效果最好但控制器和交换机之间统计采集跟不上现象网络拓扑节点多时采集所有交换机端口统计信息和 LLDP 延迟信息在 1 秒内完成不了。 原因Ryu 的 OFPMultipartRequest 请求是串行下发的交换机响应延迟叠加之后1 秒内可能只完成一半采集。 解决分段采集。把统计请求批量下发用 asyncio 并行等待响应。如果还是超时就把 Dt 改成 2 秒别看论文说 1 秒最好实际环境里采集不全的话信息就是噪声。我的经验是 Dt 不小于单轮采集时间的 1.5 倍。6. 如何把 DRL-Routing 用在自己的项目里验证方法与进阶方向拿到论文算法后建议先用一个简单拓扑验证基础逻辑再逐步放大。我的验证顺序是先建一个 6 节点的环形拓扑链路带宽不对称比如两条 5 Mbps四条 10 Mbps流量从一侧注入看智能体能否避开 5 Mbps 的瓶颈链路。这个拓扑训练时间只需要几分钟比直接上 NSFNet 快得多适合做代码调试和 reward 合理性检查。验证通过后再切换到论文的三种拓扑做全量实验。我的做法是把三种拓扑的对比结果画成一张曲线图横轴是训练步数纵轴是回合奖励均值。会看到 DRL-Routing 的曲线在 2000 步左右开始超过 OSPF 和 LL 的静态奖励线。要验证奖励函数的双向优化效果可以分别跑 φ1 和 φ0.5 两个版本对比 TCP 下载和上传混合流量下的总吞吐率——如果 φ0.5 版本的混合吞吐率高于 φ1说明双向优化确实有效。更进一步可以在同一套代码里换掉 Dueling DQN试试 Rainbow 的其他组件组合。比如在奖励函数中加入拥塞惩罚项当某条链路利用率超过 0.8 时奖励减去一个惩罚系数。这个改动能迫使智能体在做路由决策时主动避免过度集中流量而不是只在拥塞发生后才调整。实验时对比有无惩罚项的链路利用率分布能明显看到惩罚项让负载更均衡。论文使用的是确定性更新的网络体系架构实际在真实网络中带宽波动性比较强设定固定的更新周期更稳定。另外建议把训练好的模型冻结只用它做在线前向推理不进行在线学习。SDN 控制器环境数据是非平稳的在线学习容易让网络参数发生漂移冻结模型推理更稳定且控制器推理延迟可以控制在毫秒级。如果网络拓扑变化太频繁就定期离线用新数据重新训练把新模型热更新到控制器。正如论文所述经过连续训练得到的智能体已掌握了路由知识能够直接用于实际网络拓扑的部署。从那以后我每次在 Ryu 上部署这类算法都会进行验证按照上面的顺序先跑通链路再上线希望这些经验能帮到正在复现的工程师。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。