
目录
疑问?
我们都知道分组交换采用存储转发的技术,路由器收到相关分组后,会先存储到其内存中,然后查询路由表后再进行转发,如果此时路由器发生故障(如突然断电),那是不是我这个路由器上的存储的分组就丢失了呢?
答案:是的,如果路由器在分组还没有转发出去之前突然故障,这些存储在缓冲区(Buffer)中的分组通常就会丢失。
那实际生产中分组交换的可靠性来自哪里呢?接着往下看。
谁保证了可靠性?
分组交换为什么要存储转发?
假设有一个数据包
PC A
│
│ IP Packet
▼
Router1
│
▼
Router2
│
▼
Server
Router1收到完整的数据包以后,会经历几个步骤:
① 接收整个数据包
② 放入缓存(Buffer)
③ 检查IP头
④ 查询路由表(FIB)
⑤ 找到下一跳
⑥ 放入发送队列
⑦ 发出去
所以它确实要"存储",且这个存储一般不是硬盘,而是内存 RAM(Buffer),通常就是几十MB、几百MB甚至更大的高速缓存。
如果这时候路由器坏了包会丢吗?
答案:一定会丢。
例如:
PC
│
▼
Router1
↑
Packet
正在Buffer里面
突然:
Router1
Power Off
那么RAM里的Buffer全部没了
因为RAM断电即失,所以这个Packet真的丢了。
这就是 Packet Loss(丢包),互联网允许发生丢包。
为什么互联网还能正常通信?
答案:IP协议本身就是不可靠协议(Best Effort)。
IP协议只保证:尽力帮你送达。
它不会保证:
- 一定送到
- 一定按顺序
- 一定不重复
- 一定不丢
所以RFC里面把IP叫:Best Effort Delivery(即尽力而为)。
那是谁保证可靠?
答案:主要是 TCP。
例如:
发送100个Packet
1
2
3
4
5
...
100
Router2坏了,导致:
Packet
45
46
47
丢失
接收端收到:
1
2
3
...
44
48
49
...
100
TCP就会马上发现:
45呢?
没收到
于是:
ACK
一直ACK 44 或者发送SACK信息。
发送端发现:
哦
45没到
重新发送:
45
46
47
因此应用层感觉不到,因为TCP帮你补发了。
UDP怎么办?
答案:UDP没有重传,是一种不可靠的传输协议。
如果 Packet 丢了,就是真的没了。
例如:视频会议第324帧丢了,就直接播放下一帧,不会补,因为补回来已经晚了。
整个路由器坏了后面传输又怎么办?
答案:动态路由
例如:
R2
/
PC--R1
\
R3
正常:
PC
↓
R1
↓
R2
↓
Server
R2坏了,路由协议会重新收敛:
PC
↓
R1
↓
R3
↓
Server
这就是动态路由,设计到的相关协议为:
- OSPF
- IS-IS
- RIP
- BGP
路由器会根据这些协议重新计算最短路径,于是后续Packet就会走另一条路。
注意:已经在R2缓冲区里的那些Packet还是会丢,只是之后的新Packet改走别的路,最终通过 TCP 可靠传输协议对丢失部分的数据进行重传。
其他疑问?
路由器为什么不把Packet写磁盘?
答案:因为磁盘的读写速率太慢。
也许你会想:既然RAM会丢,为什么不存SSD?
原因很简单,磁盘读写速度太慢(即便是 SSD)。
例如:一个100G接口 ≈ 12.5GB/s
如果每个Packet都:
写SSD
↓
读SSD
↓
发送
延迟会暴涨,而互联网要求延迟几十微秒、甚至几微秒,SSD根本来不及。
因此,所有高性能路由器都是:
Packet
↓
ASIC
↓
Buffer(RAM)
↓
发送
而不会落盘。
如果路由器Buffer满了怎么办?
答案:路由器主动丢包
例如:出口1G,入口10G
瞬间:100万个Packet进入
Buffer 放不下,于是直接Drop,这叫 Tail Drop 或 RED(Random Early Detection),即主动提前丢一些包。
TCP看到丢包以后降低发送速度,形成TCP拥塞控制。
所以,丢包并不是异常,而是互联网正常运行的一部分。
结论
互联网并不是依靠路由器保证数据不丢,而是依靠端到端协议(主要是 TCP)和网络冗余来保证最终可靠。