为什么 TCP 协议有性能问题 ·(一)

2020 年 1 月 02 日

为什么 TCP 协议有性能问题 ·(一)

为什么这么设计(Why’s THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点、对具体实现造成的影响。如果你有想要了解的问题,可以在文章下面留言。


TCP 协议可以说是今天互联网的基石,作为可靠的传输协议,在今天几乎所有的数据都会通过 TCP 协议传输,然而 TCP 在设计之初没有考虑到现今复杂的网络环境,当你在地铁上或者火车上被断断续续的网络折磨时,你可能都不知道这一切可能都是 TCP 协议造成的。本文会分析 TCP 协议为什么在弱网环境下有严重的性能问题1


底层的数据传输协议在设计时必须要对带宽的利用率和通信延迟进行权衡和取舍,所以想要解决实际生产中的全部问题是不可能的,TCP 选择了充分利用带宽,为流量而设计,期望在尽可能短的时间内传输更多的数据2


在网络通信中,从发送方发出数据开始到收到来自接收方的确认的时间被叫做往返时延(Round-Trop Time,RTT)。


弱网环境是丢包率较高的特殊场景,TCP 在类似场景中的表现很差,当 RTT 为 30ms 时,一旦丢包率达到了 2%,TCP 的吞吐量就会下降 89.9%3,从下面的表中我们可以看出丢包对 TCP 的吞吐量极其显著的影响:


RTTTCP 吞吐量TCP 吞吐量(2% 丢包率)
0 ms93.5 Mbps3.72 Mbps
30 ms16.2 Mbps1.63 Mbps
60 ms8.7 Mbps1.33 Mbps
90 ms5.32 Mbps0.85 Mbps


本文将分析在弱网环境下(丢包率高)影响 TCP 性能的三个原因:


  • TCP 的拥塞控制算法会在丢包时主动降低吞吐量;

  • TCP 的三次握手增加了数据传输的延迟和额外开销;

  • TCP 的累计应答机制导致了数据段的传输;


在上述的三个原因中,拥塞控制算法是导致 TCP 在弱网环境下有着较差表现的首要原因,三次握手和累计应答两者的影响依次递减,但是也加剧了 TCP 的性能问题。


拥塞控制


TCP 拥塞控制算法是互联网上主要的拥塞控制措施,它使用一套基于线増积减(Additive increase/multiplicative decrease,AIMD)的网络拥塞控制方法来控制拥塞4,也是造成 TCP 性能问题的主要原因。


第一次发现的互联网拥塞崩溃是在 1986 年,NSFnet 阶段一的骨干网的处理能力从 32,000bit/s 降到了 40bit/s,该骨干网的处理能力直到 1987 和 1988 年,TCP 协议实现了拥塞控制之后才得到解决5。正是因为发生过网络阻塞造成的崩溃,所以 TCP 的拥塞控制算法就认为只要发生了丢包当前网络就发生了拥堵,从这一假设出发,TCP 就使用了慢启动和线增积减6的机制实现拥塞控制。



图 1 - TCP 的拥塞控制机制


每一个 TCP 连接都会维护一个拥塞控制窗口(Congestion Window),拥塞控制窗口的作用有两个:


  1. 防止发送方向接收方发送了太多数据,导致接收方无法处理;

  2. 防止 TCP 连接的任意一方向网络中发送大量数据,导致网络拥塞崩溃;


除了拥塞窗口大小(cwnd)之外,TCP 连接的双方都有接收窗口大小(rwnd),在 TCP 连接建立之初,发送方和接收方都不清楚对方的接收窗口大小,所以通信双方需要一套动态的估算机制改变数据传输的速度,在 TCP 三次握手期间,通信双方会通过 ACK 消息通知对方自己的接收窗口大小,接收窗口大小一般是带宽延迟乘积(Bandwidth-delay product, BDP)决定的7,不过在这里我们就不展开介绍了。


客户端能够同时传输的最大数据段的数量是接收窗口大小和拥塞窗口大小的最小值,即 min(rwnd, cwnd)。TCP 连接的初始拥塞窗口大小是一个比较小的值,在 Linux 中是由 TCP_INIT_CWND 定义的8


C


/* TCP initial congestion window as per rfc6928 */#define TCP_INIT_CWND    10
复制代码


初始拥塞控制窗口的大小从出现之后被多次修改,几个名为 Increasing TCP’s Initial Window 的 RFC 文档:RFC24149、RFC339010 和 RFC692811 分别增加了 initcwnd 的值以适应不断提高的网络传输速度和带宽。



图 2 - TCP 拥塞控制窗口的线増积减


如上图所示,TCP 连接发送方的拥塞控制窗口大小会根据接收方的响应而变化:


  1. 线性增长:当发送方收到了接收方的 ACK 时,拥塞窗口大小会加一;

  2. 积式减少:当发送方发送的数据包丢包时,拥塞控制窗口会减半;


如果 TCP 连接刚刚建立,由于 Linux 系统的默认设置,客户端能够同时发送 10 个数据段,假设我们网络的带宽是 10M,RTT 是 40ms,每个数据段的大小是 1460 字节,那么使用 BDP 计算的通信双方窗口大小上限应该是 35,这样才能充分利用网络的带宽:


然而拥塞控制窗口的大小从 10 涨到 35 需要 2RTT 的时间,具体的过程如下:


  1. 发送方向接收方发送 initcwnd = 10 个数据段(消耗 0.5RTT);

  2. 接收方接收到 10 个数据段后向发送方发送 ACK(消耗 0.5RTT);

  3. 发送方接收到发送方的 ACK,拥塞控制窗口大小由于 10 个数据段的成功发送 +10,当前拥塞控制窗口大小达到 20;

  4. 发送方向接收方发送 20 个数据段(消耗 0.5RTT);

  5. 接收方接收到 20 个数据段后向发送方发送 ACK(消耗 0.5RTT);

  6. 发送方接收到发送方的 ACK,拥塞控制窗口大小由于 20 个数据段的成功发送 +20,当前拥塞控制窗口大小达到 40;


从 TCP 三次握手建立连接到拥塞控制窗口大小达到假定网络状况的最大值 35 需要 3.5RTT 的时间,即 140ms,这是一个比较长的时间了。


早期互联网的大多数计算设备都通过有线网络连接,出现网络不稳定的可能性也比较低,所以 TCP 协议的设计者认为丢包意味着网络出现拥塞,一旦发生丢包,客户端疯狂重试就可能导致互联网的拥塞崩溃,所以发明了拥塞控制算法来解决该问题。


但是如今的网络环境更加复杂,无线网络的引入导致部分场景下的网络不稳定成了常态,所以丢包并不一定意味着网络拥堵,如果使用更加激进的策略传输数据,在一些场景下会得到更好的效果。


本文转载自 Draveness 技术博客。


原文链接:https://draveness.me/whys-the-design-tcp-performance


2020 年 1 月 02 日 15:31328

评论

发布
暂无评论
发现更多内容

Python的四种作用域及调用顺序

Young先生

Python 局部作用域 全局作用域

区块链加持的家用摄像头能拯救你的隐私吗?

CECBC区块链专委会

图解:如何实现最小生成树

淡蓝色

Java 数据结构 算法

以中立性的立场看Severless的目标和流派

韩超

云原生 serverles

LeetCode题解:141. 环形链表,JavaScript HashMap,详细注释

Lee Chen

LeetCode 前端进阶训练营

毕业半年的憨憨,将公司的代码上传到GitHub上了

诸葛小猿

GitHub 代码上传

《北京市政务服务领域区块链应用创新蓝皮书(第一版)》正式发布

CECBC区块链专委会

【API进阶之路】老板给我涨薪30%!如何通过SDK接口搞定千万级流量直播

华为云开发者社区

运维 服务器 直播 云服务 华为云

林左鸣 史瑞华:人类应鼎力进行的探索

CECBC区块链专委会

可读代码编写炸鸡七 - 表达式太长就拆

多选参数

代码质量 代码组织 代码规范 可读代码编写 可读代码

防止数据重复提交的6种方法(超简单)!

王磊

Java

第六周总结

Geek_a327d3

Week 06学习总结

Jeremy

解决问题 1474 个,Flink 1.11 究竟有哪些易用性上的改善?

Apache Flink

flink

30分钟学会应用正则表达式

墨灵

正则表达式 前端进阶训练营

可读代码编写炸鸡六 - 控制流尽量向前奔涌就好,不要分心

多选参数

代码 代码优化 代码规范 可读代码编写 可读代码

MQTT的搭建、测试、应用及小程序的集成!

诸葛小猿

物联网 IoT mqtt broker

Flask-Restful 中 fileds.DateTime 不支持 strftime 格式

Leetao

Python flask web开发 Python框架 flask-restful

聊聊Dubbo(二):简单入门

猿灯塔

Week 06 命题作业

Jeremy

单例模式的几种写法你用的哪种?

Java小咖秀

Java 设计模式 23种设计模式

朱嘉明:区块链成为经济转型、形成产业新业态的技术手段

CECBC区块链专委会

第六周作业

Geek_a327d3

寻找握剑的手,青睐懂行的人

脑极体

我想模糊删除redis key🤔

山中兰花草

Java lua redis 面试 批量任务

CAP原理

jason

企业架构框架之TOGAF

Winfield

企业架构

平价又好用的学习电脑小轩PRO来啦,为孩子创造超强学习体验

飞天鱼2017

如何进行需求梳理及埋点方案设计

易观大数据

分布式事务解决方案Seata源码解析

Chank

Java 分布式 分布式事务

计算机揭秘之:网络分类和性能分析

程序那些事

TCP 计算机网络 网络协议 计算机基础 udp

为什么 TCP 协议有性能问题 ·(一)-InfoQ