流量管理与控制
每一对源和目的都独立选择最短路时,许多流可能同时挤到少数链路上。这个问题可以分三个层次处理:网络层通过流量工程安排路径,传输层由端系统控制发送速率,链路层在节点内管理队列。
流量工程
流量工程通过调整路由,让全网流量与链路容量更匹配。传统链路权重常按物理距离设置,或与链路带宽成反比;更直接的方法是测量业务需求和网络性能,根据优化目标反推链路权重,再由现有最短路协议生成新的路由表。
实现上有两条路:一是各节点根据分布式测量结果运行自适应路由协议,按负载和需求计算路径;二是集中收集拓扑、流量和性能,运行全网“what-if”模型,统一调整影响路由的静态参数。其中,集中式方法更常用。
拥塞与端到端控制
当进入网络的负载超过可用容量时会发生拥塞。队列先变长,时延增加;缓存装满后开始丢包;端系统若把丢包一律用重传补回,又会进一步增加负载,甚至出现发送量增加而有效吞吐量下降的恶性循环。
端系统通常从往返时延(RTT)、超时和重复ACK推断拥塞,再用拥塞窗口\(cwnd\)限制尚未确认的数据量。TCP还有接收窗口\(rwnd\),用于防止发送端压满接收缓存。实际发送窗口取两者较小值:
二者形式相近,目的不同:\(rwnd\)保护接收端,\(cwnd\)保护网络。
AIMD、慢启动与拥塞避免
拥塞控制的基本原则是加性增、乘性减(AIMD):传输成功时逐渐增加窗口,发现拥塞时迅速减小窗口。\(cwnd\)实际表示允许发送的最大字节数;下面为了说明算法,用一个最大报文段MSS作为窗口单位。
连接开始时令\(cwnd=1\)。慢启动阶段每收到一个新报文段的ACK,\(cwnd\)增加\(1\,\mathrm{MSS}\);一轮RTT内大约会收到\(cwnd\)个ACK,所以窗口每个RTT近似翻倍:
当\(cwnd\)达到慢启动门限\(ssthresh\)后,进入拥塞避免阶段,每个RTT只增加约\(1\,\mathrm{MSS}\),窗口近似线性增长。若\(cwnd=W\)时发生超时,则令
随后重新慢启动,到达新门限后再转为线性增长。这样做体现了“没有拥塞时试探性增加,发现拥塞时立即退让”。
TCP本身还提供面向连接、可靠且有序的字节流服务。连接通过三次握手建立,双方用序号、校验和、ACK和重传处理差错与乱序。正常拆除双向连接时,双方分别发送FIN并确认,形成四次握手;RST则用于直接关闭连接,不再接收余下数据。
队列管理
路由器线路卡要完成包转发、缓存、过滤和链路调度。缓存能吸收短时突发,却不能无限增大:缓存太小容易丢包,太大又会把排队时延推高。因此队列管理既要决定何时丢、丢哪个包,也要决定下一步发送哪个包。
最简单的方案是FIFO加队尾丢弃(Drop-Tail):分组按到达顺序发送,队列满时丢掉新到分组。它实现容易,却要等缓存完全填满才给出拥塞信号。多个TCP连接可能同时看到丢包、同时减小窗口,之后又同时增长,形成全局同步。
提前随机丢包的思路,是在队列尚未满时就随机丢弃少量分组。丢弃概率随平均队列长度增加,队列满时取\(1\)。发送速率越高的连接,到达的分组越多,被提前选中的概率也越高;先让少数连接减速,可以避免等到队列溢出时让大量连接同时发现丢包。
左图把课件中的窗口过程连起来:慢启动到门限后改为线性增长,超时后\(cwnd\)回到\(1\),门限更新为原窗口的一半。右图对应随机早期检测(RED):平均队列较短时不丢包,随后逐步提高提前丢包概率,队列满时概率达到\(1\)。
调度策略决定队首之后究竟服务哪一类流:
- FIFO最简单,但不能照顾实时业务的低时延需求。
- 严格优先级先服务高优先级队列,可以让高优先级业务近似使用专用链路,但会压缩低优先级业务的传输机会。
- 加权公平调度按预定比例使用各队列,在带宽份额、时延和公平性之间作更灵活的折中。
流量工程、端到端拥塞控制和队列管理不是互相替代的方案。前者从全网改变流量走向,中间层让发送端适应路径容量,最后一层处理链路上的瞬时竞争,三者共同决定吞吐量、丢包率和时延。
