Search K
Appearance
Appearance
看了前面的重传的文章,你可能有一个疑惑,到底隔多久重传才是合适的呢?间隔设置比较长,包丢了老半天了才重传,效率较低。间隔设置比较短,可能包并没有丢就重传,增加网络拥塞,可能导致更多的超时和重发。

因此间隔多久重传就是不是一成不变的,它随着不同的网络情况需要动态的进行调整,这个值就是今天要介绍的「超时重传的时间」(Retransmission TimeOut,RTO),它与 RTT 密切相关,下面我们来介绍几种计算 RTO 的方法
一个最简单的想法就是取平均值,比如第一次 RTT 为 500ms,第二次 RTT 为 800ms,那么第三次发送时,各让一步取平均值 RTO 为 650ms。经典算法的思路跟取平均值是一样的,只不过系数不一样而已。
经典算法引入了「平滑往返时间」(Smoothed round trip time,SRTT)的概念:经过平滑后的 RTT 的值,每测量一次 RTT 就对 SRTT 作一次更新计算
SRTT = ( α * SRTT ) + ((1- α) * RTT)
α 是平滑因子,建议值是 0.8 ~ 0.9。假设平滑因子 α = 0.8,那么 SRTT = 80% 的原始值 + 20% 的新采样值。相当于一个低通滤波器。
超时重传时间 RTO 的计算公式是:
RTO = min(ubound, max(lbound, β * SRTT))其中 β 是加权因子,一般推荐值为 1.3 ~ 2.0。ubound 为 RTO 的上界(upper bound),lbound 为 RTO 的下界(lower bound)。
这个公式的含义其实就是,RTO 是一个 1.3 倍到 2.0 倍的 SRTT 值,最大不超过最大值 ubound,最小不小于最小值 lbound

这个算法下,平滑因子 α 取值范围是 0.8 ~ 0.9,RTT 对 RTO 的影响太小了,在相对稳定 RTT 的网络环境中,这个算法表现还可以,如果在一个 RTT 变化较大的环境中,则效果较差。
于是出现了新的改进算法:标准方法。
传统方法最大的问题是 RTT 有大的波动时,很难即时反应到 RTO 上,因为都被平滑掉了。标准方法对 RTT 的采样增加了一个新的因素,
公式如下
SRTT = (1 - α) * SRTT + α * RTT
RTTVAR = (1 - β) * RTTVAR + β * (|RTT-SRTT|)
RTO= µ * SRTT + ∂ * RTTVar先来看第一个计算 SRTT 的公式
SRTT = (1 - α) * SRTT + α * RTT这个公式与我们前面介绍的传统方法计算 SRTT 是一样的,都是新样本和旧值不同的比例权重共同构成了新的 SRTT 值,权重因子 α 的建议值是 0.125。在这种情况下,SRTT = 87.5% 的原始值 + 12.5% 的新采样值。

第二个公式是计算 RTTVAR:「已平滑的 RTT 平均偏差估计器」(round-trip time variation,RTTVAR)
RTTVAR = (1 - β) * RTTVAR + β * (|RTT-SRTT|)
平均偏差是标准方差的良好近似,计算较为容易,无需标准方差的求平方根运算。如果 β 取建议值 0.25 则
RTTVAR
= 0.75 * RTTVAR + 0.25 * (|RTT-SRTT|)
= 75% 的原始值 + 25% 的平滑 SRTT 与最新测量 RTT 的差值第三个公式计算最终的 RTO 值
RTO = µ * SRTT + ∂ * RTTVARμ 建议值取 1,∂ 建议值取 4,则
RTO = SRTT + 4 * RTTVAR这种算法下 RTO 与 RTT 变化的差值关系更密切,能对变化剧烈的 RTT 做出更及时的调整。
前面的算法都很精妙,但是有一个最基本的问题还没解决,如何重传情况下计算 RTT,下面列举了三种常见的场景

当客户收到重传过的某个请求的一个应答时,它不能区分该应答对应哪一次请求。
上面的这种问题,就称为「重传二义性」(retransmission ambiguity problem)
Karn / Partridge 算法就是为了解决重传二义性的。它的思路也是很奇特,解决问题的最好办法就是不解决它:
仅仅有上面的规则是远远不够的,放弃掉重传那次不管看起来就像遇到危险把头埋在沙子里的鸵鸟。如果网络抖动,倒是突然出现大量重传,但这个时候 RTO 没有更新,就很坑了,本身 RTO 就是为了自适应网络延迟状况的,结果出问题了没有任何反应。这里 Karn 算法采用了出现重传就将 RTO 翻倍的方法,这就是我们前面看到过的指数级退避(Exponential backoff)。这种方式比较粗暴,但是非常简单。
这篇文章我们讲了 RTO 的由来和计算 RTO 的经典方法和标准方法的计算方式:
最后的部分引入了「重传二义性」的概念,看到了计算重传情况下 RTT 的困难之处,由此引入了 Karn 算法: