按关键词阅读:
文章插图
然而这在实现中是不易发生的 , 是什么限制住它的发生呢?以下几点:
1.TCP的延迟确认机制最多只能延迟2个MSS
慢启动增窗 , 收到一个ACK递增1个MSS , 即便在使用ABC的时候 , 也就是说窗口最多只能超越ssthresh 2个MSS , 这是由下述代码保证的:
if (sysctl_tcp_abc > 1
2.即便发生了ACK大量丢失 , TCP的默认实现也是数ACK的个数 , 而不是数被ACK的字节数
3.发生大量ACK丢失又启用ABC时 , 见方法1.
4.两段处理方式
Linux的4.x版本内核中默认使用ACK的字节数来计数增窗值(ABC方案) , 在穿越ssthresh的时候 , TCP拥塞控制逻辑会将被ACK的字节数分为两个部分 , ssthresh以下的部分用来计数慢启动 , 而ssthresh以上的部分用来计数拥塞避免 。 综上所述 , 下图总结了ssthresh穿越的情况:
文章插图
AIMD的公平性收敛为了简单起见 , 我们假设有TCP1和TCP2两个连接共享一个链路 , 现在看它们是怎么“收敛到公平”的 , 下面的图示清晰显示了一切:
文章插图
如果你看不懂这个图 , 请自行google 。 我们可以肯定 , 在公平线的下方 , 红色的减窗线的斜率是恒小于公平线(斜45度角)的斜率的 , 两个链接的每一次降窗 , 其降窗线的斜率都会越来越接近公平线的斜率 , 即收敛到公平 , 最终 , 它将在绿色粗线上震荡 , 永葆公平(虽然利用率不是那么高!) 。
我们还可以看到 , TCP1和TCP2是等比例降窗的 , 在此例中比例是0.5 , 它们非得是0.5吗?非也!只要保持等比例 , 图中的注解1就永远成立 , 最终的收敛也会永远成立 , 不同的仅仅是最终收敛额绿色粗线的长度和范围!虽然说按照最初的Reno TCP , 保持0.5的降窗比例是多么得合理(见上述推论) , 然而考虑到现实的复杂情况 , 比例不再是0.5也是合理的 。现在我们来看看如果TCP1和TCP2的降窗比例不同会怎样 。 假设TCP2降窗依然为0.5的比例 , 而TCP2则小于0.5 , 那么上图将会变成下面的样子:
文章插图
我们可以看到 , 竞争者中降窗比率最小的将会最终抢占几乎所有的带宽 , 它会将所有的其它连接的带宽逐渐往左上角挤兑 , 最终归零 。 这么说来 , 如果想让自己的TCP具有侵略性 , 减少降窗比率是不是就可以了呢?没这么这简单!要知道 , 我上面的两幅图有一个共同的前提 , 那就是竞争者的RTT是相等的!但是现实中 , 会这样吗??非常难!如果RTT相等 , 比如它们的源头和目标都在同一个地点 , 那么它们十有八九是合作关系 , 而不是竞争!爆炸!
【TCP—慢启动、ssthresh、拥塞避免、公平性的真实含义】 那么 , RTT将会是一个十分重要的角色!确实是这样 , 实际的TCP在运行中 , RTT的波动非常大 , 这就几乎将我上面的论述全部推翻了 , 显然很令人心碎!然而 , 上述的分析作为一个理论模型还是有意义的 , 它起码让你理解了TCP的本质行为 。 至于说实际情况 , RTT的波动是一个有意义的信号 , 它让端系统看到了中间路由器交换机的排队行为 , 因此会出现RTT所谓的“噪点” , 很多人想除掉它们 , 平滑掉它们 , 但是这同时也意味着你屏蔽了重要的信号 。RTT的波动非常具有动感且性感 , 它用数值表征了整个排队理论 , 或者你可以推出马尔科夫到达过程 , 或者你只是觉得它们是令人难过的噪点...于是 , 现实中的TCP几乎完全改进了Reno的指导 , 除了Reno几乎没有什么拥塞算法在发现丢包时把ssthresh降为当前窗口的一半 。 这就是TCP的进化 , 但是这种进化始终围绕着一个内核 , 这个内核就是我上面说的这些 , 简单 , 易懂 , 然而却令人惊讶的东西 。
稿源:(未知)
【傻大方】网址:http://www.shadafang.com/c/111J2SH2020.html
标题:TCP—慢启动、ssthresh、拥塞避免、公平性的真实含义( 三 )