目录
- 导语
- [一、5.2.1 链路状态路由选择算法](#一、5.2.1 链路状态路由选择算法)
- [二、5.2.2 距离向量路由选择算法](#二、5.2.2 距离向量路由选择算法)
- [三、LS vs DV:一场全局与分布式的较量](#三、LS vs DV:一场全局与分布式的较量)
- 本节核心总结(必看)
- 结语
导语
大家好呀~这一节是第5章的理论核心------路由选择算法(Routing Algorithm)!如果说控制平面是网络的"大脑",那路由选择算法就是大脑里的"思维方式"------它决定了路由器如何计算从源到目的地的最优路径。
路由选择算法是计算机网络中最经典、最优雅的算法之一。我们要学习两种最基本的算法:链路状态算法(Link State,LS)和距离向量算法(Distance Vector,DV) 。LS算法用的是大名鼎鼎的Dijkstra最短路径算法 ,DV算法用的是Bellman-Ford方程。这两种算法不仅是网络路由的基础,也是图论和算法课程的核心内容。
这一节会有一些数学推导和算法步骤,但别怕,我们会用通俗的类比和具体的例子来讲解。理解了这两种算法,后面学OSPF和BGP就会非常轻松------OSPF就是LS算法的工程实现,BGP就是DV算法的策略增强版。准备好了吗?让我们开始这场算法之旅~

一、5.2.1 链路状态路由选择算法
1. 基本思想:每个人都有完整地图
**链路状态算法(Link State Algorithm)**的核心思想很简单:每个路由器都掌握全网的完整拓扑图,然后各自用Dijkstra算法计算从自己到所有目的地的最短路径。
通俗类比:LS算法就像每个人手机里都有一份完整的城市地图(高德/百度地图),你输入目的地后,导航软件根据完整地图计算最优路线。每个人的地图都是一样的(因为大家都共享路况信息),所以每个人算出来的路线也是一致的。
LS算法的工作分为两步:
第一步:链路状态泛洪(Flooding)
每个路由器测量自己到邻居的链路代价,然后把这些信息(链路状态分组,LSP)通过**泛洪(flooding)**的方式发送给全网所有路由器。泛洪就是:收到LSP后,除了入端口,从所有其他端口转发出去。这样,每个路由器最终都能收到全网所有路由器的链路状态信息,构建出完整的网络拓扑图。
第二步:Dijkstra最短路径计算
每个路由器有了完整拓扑图后,以自己为源点,运行Dijkstra算法,计算到所有其他路由器的最短路径,然后生成转发表。
2. Dijkstra算法详解
Dijkstra算法是一种贪心算法,用于计算从一个源点到所有其他节点的最短路径。算法维护两个集合:
- N':已经确定最短路径的节点集合
- D(v):从源点到节点v的当前最短路径代价
算法步骤:
- 初始化:N' = {源点u},对于每个邻居v,D(v) = c(u,v)(直接链路代价),其他节点D(v) = ∞。
- 循环:在不在N'中的节点中,找到D(v)最小的节点w,把w加入N'。然后对于w的每个不在N'中的邻居v,更新D(v) = min(D(v), D(w) + c(w,v))。
- 终止:当所有节点都加入N'时,算法结束。
简单说:每次选一个离源点最近的、还没确定的节点,加入"已确定"集合,然后用这个节点更新它邻居的距离。重复直到所有节点都确定。
3. Dijkstra算法具体例子

假设有5个路由器:u、v、w、x、y,链路代价如下:
- u-v: 2, u-w: 5, u-x: 1
- v-w: 3, v-x: 2
- w-y: 1, x-y: 1
- x-w: 3
以u为源点,运行Dijkstra:
第1步:N'={u},D(v)=2, D(w)=5, D(x)=1, D(y)=∞
第2步:最小的是D(x)=1,加入x。N'={u,x}。更新邻居:D(v)=min(2, 1+2)=2,D(w)=min(5, 1+3)=4,D(y)=min(∞, 1+1)=2
第3步:最小的是D(v)=2和D(y)=2,任选一个,比如v。N'={u,x,v}。更新邻居:D(w)=min(4, 2+3)=4(不变)
第4步:最小的是D(y)=2,加入y。N'={u,x,v,y}。更新邻居:D(w)=min(4, 2+1)=3
第5步:只剩w,D(w)=3,加入w。N'={u,x,v,y,w},算法结束。
最终最短路径:u→v=2(直接),u→w=3(u→x→y→w),u→x=1(直接),u→y=2(u→x→y)。
4. LS算法的复杂度和振荡问题
Dijkstra算法的时间复杂度是O(n²)(n是节点数),用优先队列可以优化到O(n log n)。对于大型网络(几千个节点),计算量还是挺大的,但现代路由器的CPU完全能应付。
LS算法有一个潜在问题:路由振荡(route oscillation)。如果链路代价和当前流量相关(负载敏感),路由器可能会反复改变路由------流量走某条路导致这条路拥塞→代价升高→流量切换到另一条路→另一条路拥塞→代价升高→又切回来......如此反复。
解决方法:使用负载迟钝的链路代价(只和带宽、跳数等静态因素有关,不和当前拥塞程度挂钩)。现代因特网的OSPF等协议都是负载迟钝的,避免了振荡问题。
二、5.2.2 距离向量路由选择算法
1. 基本思想:只问邻居,不看全局
**距离向量算法(Distance Vector Algorithm)**的核心思想和LS完全不同:每个路由器不需要知道全网拓扑,只需要维护一个距离向量(到所有目的地的估计代价),然后定期和邻居交换距离向量,根据邻居的信息更新自己的距离向量。
通俗类比:DV算法就像你不知道整个城市的路况,但你知道到每个邻居家的距离,邻居也告诉你他们到各个地方的距离。你根据"到邻居的距离 + 邻居到目的地的距离"来估计自己到目的地的最短距离。你不需要完整地图,只需要和邻居"唠嗑"就能慢慢算出最短路径。
DV算法基于Bellman-Ford方程:
D_x(y) = min_v { c(x,v) + D_v(y) }
意思是:从x到y的最短距离 = 对所有邻居v,取(x到v的链路代价 + v到y的最短距离)的最小值。
每个路由器x维护:
- D_x(y):到目的地y的估计最短距离
- 距离向量:D_x = D_x(y): y in 所有节点
每个路由器定期把自己的距离向量发送给所有邻居。收到邻居v的距离向量后,用Bellman-Ford方程更新自己的D_x(y)。
2. DV算法的特点

DV算法有几个鲜明的特点:
(1)分布式、异步
每个路由器只和邻居交换信息,不需要全网同步。路由器可以在任意时刻更新和发送距离向量,不需要等待其他路由器。
(2)迭代收敛
距离向量不是一次就算对的,而是通过多轮和邻居交换,逐步收敛到正确值。就像谣言传播一样------信息从邻居传到邻居,慢慢扩散到全网。
(3)好消息传得快,坏消息传得慢
这是DV算法最著名的特点。如果一条链路的代价降低了(好消息),这个信息会很快通过邻居传播开,几轮就能收敛。但如果一条链路的代价升高了或者断了(坏消息),信息传播会很慢,可能需要很多轮才能收敛------这就是著名的**计数到无穷(count-to-infinity)**问题。
3. 计数到无穷问题

让我们用一个经典的例子来说明计数到无穷问题。假设有三个路由器A、B、C,链路代价都是1:
- A-B: 1
- B-C: 1
正常情况下:
- A到C的距离是2(A→B→C)
- B到C的距离是1(直接)
现在假设B-C链路断了(代价变成∞)。
B发现到C的直接链路断了,但B之前从A那里听说"A到C的距离是2"。B想:"既然A到C是2,我到A是1,那我到C就是1+2=3。"于是B更新到C的距离为3,告诉A。
A收到B的更新后想:"B到C是3,我到B是1,那我到C就是1+3=4。"于是A更新到C的距离为4,告诉B。
B收到后又更新:"A到C是4,我到A是1,我到C就是5。"告诉A......
如此循环,A和B到C的距离会不断增加:2→3→4→5→6......直到达到某个最大值(通常设为16,RIP中16表示不可达)。这就是计数到无穷------坏消息要数到无穷(实际上是数到16)才能收敛。
计数到无穷的根本原因是:A和B之间形成了"路由环路"------A以为经B能到C,B以为经A能到C,实际上C已经不可达了,但双方互相"欺骗",距离不断增加。
4. 毒性逆转(Poison Reverse)

为了解决计数到无穷问题,DV算法引入了**毒性逆转(Poison Reverse)**机制。
毒性逆转的规则:如果路由器x通过邻居v到达目的地y,那么x在发给v的距离向量中,会把到y的距离设为∞("毒化"这条路由)。这样v就不会以为经x能到y,避免了环路。
用上面的例子:正常情况下,A通过B到C(A→B→C)。那么A在发给B的距离向量中,会把到C的距离设为∞。这样当B-C链路断了之后,B不会从A那里得到"A到C=2"的错误信息(因为A告诉B的是∞),B就不会以为经A能到C,计数到无穷就不会发生了。
但毒性逆转不能完全解决计数到无穷问题------在更复杂的拓扑中(比如三个以上节点的环路),毒性逆转可能失效。所以RIP等DV协议还设置了最大跳数(16跳)作为兜底------距离到16就认为不可达,强制停止计数。
5. DV算法的其他特点
消息复杂度:DV算法只在邻居之间交换距离向量,消息量和链路数成正比(O(E)),比LS的泛洪(O(N×E))要少。
收敛速度:DV算法收敛较慢,尤其是坏消息传播慢,可能出现计数到无穷。LS算法收敛快,因为每个路由器有完整拓扑,一旦链路变化,泛洪后所有路由器同时重新计算。
健壮性:LS算法中,一个路由器的错误计算只影响自己的转发表(因为每个路由器独立计算)。DV算法中,一个路由器的错误距离向量会传播给邻居,可能影响全网(错误会扩散)。
三、LS vs DV:一场全局与分布式的较量
学完两种算法,我们来做一个全面对比。这是面试和考试的高频考点。
| 对比项 | 链路状态(LS) | 距离向量(DV) |
|---|---|---|
| 信息来源 | 全网拓扑(完整地图) | 邻居的距离向量(局部信息) |
| 算法基础 | Dijkstra最短路径 | Bellman-Ford方程 |
| 消息复杂度 | O(N×E),泛洪到全网 | O(E),只和邻居交换 |
| 收敛速度 | 快,链路变化后快速收敛 | 慢,坏消息传播慢,计数到无穷 |
| 路由振荡 | 可能(负载敏感时) | 较少 |
| 健壮性 | 好,错误只影响自己 | 差,错误会扩散给邻居 |
| 计算复杂度 | O(n²) 或 O(n log n) | 每次更新O(邻居数) |
| 典型协议 | OSPF、IS-IS | RIP、BGP(增强版) |
| 适用规模 | 中大型网络(AS内部) | 小型网络或策略路由(AS之间) |
用一句话总结:
- LS = 每个人都有完整地图,自己算路线。信息全、收敛快,但消息量大、计算复杂。
- DV = 只问邻居,慢慢打听。消息少、计算简单,但收敛慢、可能计数到无穷。
在实际因特网中,AS(自治系统)内部通常用LS算法(OSPF),因为AS内部路由器数量可控,需要快速收敛;AS之间用DV算法的增强版(BGP),因为AS之间需要策略控制,且AS数量相对较少。
本节核心总结(必看)
这一节是路由选择的理论核心,要点如下:
一、链路状态算法(LS)
- 每个路由器泛洪链路状态信息,获得全网拓扑
- 用Dijkstra算法计算最短路径
- Dijkstra:每次选最近的未确定节点,更新邻居距离
- 复杂度O(n²),收敛快,健壮性好
- 可能路由振荡(用负载迟钝代价解决)
二、距离向量算法(DV)
- 每个路由器维护距离向量,和邻居交换,用Bellman-Ford更新
- 分布式、异步、迭代收敛
- 好消息传得快,坏消息传得慢
- 计数到无穷问题:路由环路导致距离不断增加
- 毒性逆转:通过邻居的路由设为∞,部分解决计数到无穷
- 消息量少,计算简单,但收敛慢、健壮性差
三、LS vs DV
- LS:全局信息、Dijkstra、收敛快、健壮、OSPF
- DV:局部信息、Bellman-Ford、收敛慢、可能计数到无穷、RIP/BGP
关键概念清单
- 链路状态(Link State,LS):全局式路由算法
- 距离向量(Distance Vector,DV):分布式路由算法
- Dijkstra算法:LS使用的最短路径算法
- Bellman-Ford方程:DV的理论基础
- 泛洪(Flooding):LS的信息传播方式
- 计数到无穷(Count-to-Infinity):DV的收敛问题
- 毒性逆转(Poison Reverse):缓解计数到无穷的机制
- 路由振荡(Route Oscillation):LS的潜在问题
- 自治系统(AS):统一管理的路由器集合
结语
这一节我们深入学习了两种最经典的路由选择算法------链路状态和距离向量。从Dijkstra的贪心策略,到Bellman-Ford的迭代更新,从计数到无穷的经典问题,到毒性逆转的巧妙解决,每一个设计都体现了算法的智慧。
理解了这两种算法,后面学习实际路由协议就会非常轻松。下一节5.3我们将学习OSPF(开放最短路径优先)------链路状态算法在因特网中的工程实现,看看理论算法是怎么落地到真实网络中的。OSPF是企业网络和ISP内部最常用的路由协议,也是网络工程师必须掌握的协议。
如果你觉得这篇笔记对你有帮助,欢迎点赞收藏~有问题也欢迎留言讨论,我们一起进步!