快速网络的慢启动

来源:互联网 发布:深思考人工智能北京 编辑:程序博客网 时间:2024/04/29 20:43

如今的网络带宽在逐步的提高,延迟反而成了影响网络性能的重要原因。TCP 的多种机制会导致新建的连接一开始性能不高的问题。这都是为了防止TCP网络拥堵崩溃而加入的慢启动机制。

TCP 的连接建立需要经过三次握手过程,当然 TFO(TCP Fast Open)机制在一定程度上减少了握手的时间。在互联网上非常短的 TCP 连接非常常见,因此延迟所带来的影响也就非常可观,TCP 的复用也就成为了提高性能的一个有效手段。

三次握手

TCP握手
熟悉TCP的应该都很熟悉这张图,TCP建立连接的三次握手阶段,三次握手之后客户端与服务器之间就可以通信了,客户端可以在发送 ACK 之后立即发送数据,而服务器必须等接收到 ACK 分组之后才能发送数据。因此每次传输应用数据之前,都必须耗费一个 RTT 在握手阶段。

TFO 可以在支持的情况下,依赖加密的 cookie,可以随同 SYN 分组一起发送应用数据,但是数据净荷会有限制,而且只能应用在重复的连接上。

拥塞预防及控制

在节点带宽不对称的网络中,为了防止数据爆发导致的网络崩溃,TCP 中使用了很多的机制,控制双方发送数据的速度,流量控制,拥塞控制和拥塞预防。

流量控制

TCP 接收窗口
TCP 使用接收窗口(rwnd)来控制发送端过多的向接收端发送数据,建立连接时,两端使用自身系统默认的 rwnd 值来设置保存数据的缓冲区大小。然后每个 ACK 分组会通知最新的 rwnd 值,方便两端动态的调整数据流速。

TCP 最初的规范分配给通知窗口大小的字段是 16 位,相当于接收窗口的最大值为 65535 字节,在 RFC 1323 中提供了 TCP Window Scaling 选项,可以左移 16 位窗口字段,接收窗口的最大值提高到 1G 字节。

慢启动

慢启动和拥塞预防
流量控制可以有效的防止发送端过多的发送数据,但是在连接建立之初并不知道可用带宽是多少,依然有可能在建立之初就发送了过多的数据,导致网络拥塞崩溃。

因此又引入了拥塞窗口大小(cwnd),表示发送端对从客户端接收到确认 ACK 之前可以发送的数据量的限制。

两端的 cwnd 值是在本地根据算法确定的,两端不会通知对方 cwnd,cwnd 具有一个初始值,最初是 1 个 TCP 段,RFC 2581 调整为 4 个,RFC 6928 再次调整为 10 个,(一个 TCP 段是1460 字节)TCP 建立好之后,发送端能够发送数据的大小为 rwnd 和 cwnd 的最小值,在收到分组确认 ACK 之后增大 cwnd 的大小,慢慢的加快发送数据量,直到超过 rwnd 的值,也就是所谓的慢启动。

拥塞预防

那么在丢包之后又怎么处理呢,这时候拥塞预防算法就介入了。

AIMD 倍减加增算法,发生丢包时,先将拥塞窗口减半,然后每次往返再缓慢的给窗口增加一个固定的值。这种算法比较保守,有时候达不到最高的效果。

Linux 3.2+ 之后默认采用 PRR 比例降速算法,TCP 中还有非常多的算法来确保快速恢复,有空再来研究~~~

TCP 中还有一个 SSR(Slow-Start Restart,慢启动重启)机制,就是在连接空闲一定时间后重置连接的拥塞窗口。SSR 对于会出现突发空闲的长周期 TCP 连接有比较大的影响,有一种建议是最好在服务器上禁用。

带宽延迟积

拥塞窗口 cwnd 和 接收窗口 rwnd 的最小值限制了在途未确认的最大数据量,两端之间的数据超过了未确认的最大数据量,都必须等到另一方的 ACK 确认才能继续发送数据。所以应该让窗口足够的大,只要传输不中断,才能保证最大的吞吐量。

那么最优的窗口大小的值多大才合适?TCP 引入一个带宽延迟积的概念(BDP, Bandwidth-delay product),既数据链路的容量与端到端延迟的乘积。这个结果就是任意时刻处在于在途未确认状态的最大数据量,也即是窗口大小的最优值。

队首阻塞

对手阻塞
TCP 是一个可靠的传输协议,分组数据必须按序交付,如果中途有分组丢失没能到达接收端,那么后续分组必须保存在接收端的缓冲区中,等待丢失的分组重发并到达接收端。

这就会导致分组到达时间存在无法预知的延迟变化,通常称之为 抖动(jitter) ,也是影响应用程序性能的一个主要因素。

优化建议

1、使用最新版本的代码
2、适当的开启 TFO 机制
3、保证TCP窗口足够的大
4、尽可能的重用 TCP 连接
5、一定要新建连接的情况下,尽早去做
6、结合 DNS 优化

原创粉丝点击