IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> TCP拥塞控制及其缺点 与 基于UDP应用层自定义可靠有连接协议 -> 正文阅读

[网络协议]TCP拥塞控制及其缺点 与 基于UDP应用层自定义可靠有连接协议

? ? 本文前半部分为计算机网络课程最后一节课学习内容的课堂笔记,后半部分为结合最近碰巧学习了解应用层网络协议时了解到的一些内容总结到此处。阅读本文需要了解 TCP 协议与 UDP 协议的区别,了解网络五层模型,复习一般 TCP congestion control 流程(本文着重解释回顾)。阅读完后将会了解?TCP 协议的缺点不足以及一些用户态自定义协议的动机。


Congestion Control 和为什么简单的算法能工作

  • 拥塞发生的层次:需要区分 transport layer 的?端到端 vs. data link 的 p2p, 首先 端 意味着中间链路是包括各种 point (routers/swiches)的, 然后是速度问题, 层? 3 的 routing 肯定是更加 expensive 的, 层 2 的 switching 肯定比 routing 快. 如果现在想要实现更快的传输, 首选肯定是 bypass 所有的三层以上的层, 仅使用下面的一层和二层.
  • TCP 里面 和 OSI 层 2 的 Data Link Control 有着相似的功能要求, 就是 Error Control 和 retransmission (ARQ 协议,注 TCP/IP 下层没有 ARQ), 额外要添加一个 congestion control.
  • 为什么 congestion problem 非解决不可呢? 像我们之前的 网络层 的, 各种路由算法好像快的和慢的也没有什么区别? 这是因为那些问题是可选的, 更低效的算法也只是导致了性能的下降, 但是来到 transport layer 之后, 由于下面的层都是 best-effort to deliver packet(frame/datagram), 这就导致了网络无时无刻在拥堵风险中.
    • 首先区分一下 flow control 和 congestion control, flow control 解决的问题是收发两者不同步的问题, 如果收方收的慢, overwhelming ,发方要减速. 而网络环境的拥塞是一个全局性的, 如果网络拥塞了, 我们要确保发方不乱发制造更大的冲突. 也就是 p2p 和 点到网络环境的区别.
    • 如果不解决 congestion 问题, 网络就会瘫痪.
  • 比较快乐的一点的, TCP 用分布式算法 解决了全局优化的问题. 这一点在以后很多系统和工程上都见得到.
  • 然后是工程上很多复杂问题都采用简单的算法解决, 这不是儿戏化也不是不思进取, 而是实际 测量出来的最优选择. 就好像 Cache 中用 LRU 和 random 算法, 实际上 random 也不差以及 Deep Learning 里 activating 用 ReLU 不用其他如 sigmoid 等或者更加复杂的并不是偷懒, 而是实际跑出来的效果很好

TCP congestion control 算法

? ? 三种算法 Taho TCP, Reno TCP, and New Reno TCP. 这里针对基本的相同部分解释几个要点,一个是为什么会有 dupACK,这是因为接收方不断接受到新的包但是却缺少某个顺序中前面的包,所以无法发行新编号的 ACK 而要发送未收到的那个包。然而 TCP 已经发送过未收到的那个包,timer 还在倒计时。time-out 或者收到3个 dupACK 说明丢包,网络可能拥塞了(之后否定这条)。

? ? 普通 Taho TCP 的状态机

? ? Reno TCP 讲解

? ? 我就具体讲这个 Reno TCP 吧, 也就是课上老师讲解的. 首先注意 cwnd 的单位是 MSS 最大报文段长度,然后 cwnd + 1 的意思是一个 RTT 加1,而一次发 n 个包,?ACK n 个包则加 n,所以是翻倍。

  • 区分拥塞和网络质量:之前我们遇到timeout(依据重传超时时间(RTO)) 和 triple dup-ACK 的时候, 都认为是 congestion 了, 这一点不实.
  • 更好的拥塞判定:实际上如果真的发送了 congestion, 肯定是 timeout 更可能吧, 毕竟你还能发 ACK 给我收到, 说明实际上也没有多拥塞,
  • 网络质量判定:不过既然你发了 3个 dupACK? 给我, 我认为你在急需重排(re-ordering)并 free receiving window, 所以我要 fast retransmit, 但是同时不要回到 1, 因为可能只是丢了一个包, 没必要拥塞认定
  • 进入快恢复与重传:为什么继续增加仅仅重传而要减半?? 减半是为了暂停最新包的后续包的发送(这部分包只会加入接收方重排而不会进行 ACK)而避免引发更多 dupACK, 那这里就涉及到 rwnd 有限和避免导致拥塞, 如果我持续增加同时重传就导致我在引发 congestion 了. 而 +3 是因为 3个 ACK 之间我肯定还发多了3个还没?ack 的 datagrams,这3个虽然还没有明确地确认,但已经隐含地确认了。?+3 能防止他们在将来重传(记住此时 window 的 left most 就是那个可能丢的包,所以至少让窗口为这么大:“ 【lost】【+1】【+2】【+3】”)。
  • 快恢复持续 dupACK:进入一个Fast recovery 的状态就是如果这个时候又持续收到了 dup 的ACK, 说明持续在丢包, 他就激进地仿佛 slow start 那样, 一边重传一边继续后续的发送, 仍然是指数型的增长, 所以这里增加窗口大小是为了持续保留重传后的 buffered data 这些虽然还没有明确地确认,但已经隐含地确认了。并且持续发送新的 unsent 出去。
  • 正常:一旦获得了新的 ACK, 说明我不需要重传了! 这时候就进入刚才减半的 threshold 进入 CA 状态吧.

? ? 再看一下 cwnd (congestion control window) 的调整趋势图:

? ? 然后再改进的话还有方法就是上文中 more than one lost 的情况, 这里我不探讨了. 有时间看一下文字补充一下吧…但是实际上, 在高速网络上, 由于他这个拥塞避免下太保守了, 就还提出了 CUBIC 和 BIC 算法, Linux 一般用 Reno, Windows 下用的默认是 CUBIC, 还有 new Reno 以及一些其他的没学过的. 后续网络课程持续学习,可以基于 UDP 编写一个用户态网络栈。


BBR 算法

  • 全称是:bottleneck bandwidth and round-trip propagation time
  • 我们之前说过, TCP 的 Congestion Control 算法是一个 distributed 的应用, 而且各厂商可以自己乱改一套, 反正他和 flow control 的不一样, 他是发端自己检测 network quality 自己控制自己, 区别于 flow control 的 receiver notify sender 必须双方知会.
  • 前面说我们用简单的算法也能 work 而且效果还不错(曾经),但是其实既然我们都搞闭环系统控制了,不如采集多点数据分析网络情况,搞一个能尽可能拟合理想 througput 曲线的算法。
  • 下面学习一下最新的 BBR 算法对比 Reno 的点.

Linux 4.9 kernel 采用了 BBR 算法. 中科大有人测试了出口网络访问服务器提速数十倍: Linux Kernel 4.9 中的 BBR 算法与之前的 TCP 拥塞控制相比有什么优势?

  • BBR 解决的主要问题是再丢包链路上充分利用带宽. 之前我们 Reno 引入了 Fast recovery 来进行丢包链路带宽利用, 办法是引入快重传.
  • 老师讲课时讲到了这个 RTT 的检测是十分复杂和 tricky 的, 可惜教学大纲限定无法展开.
  • 我得了解一下这个, 我们 Reno 算法在 slow start 的时候是一个 ack 来就搞一个递增, 实际上看就是一个 RTT(round trip time) 倍增了. 注意这里的 RTT 是指一个 sender wnd 发完的 RTT. 但是由于 ACK 不一定就在相同的时间发来, 也就是 一个 RTT 并不能严格对应多个的 ACK, 也就是实际 Reno 的倍增速度是没有理论上的 2 to the power of n 的 exponential growth 的.
  • 看看BBR干了什么, BBR 就不是根据 ACK 来增加 cwnd 了, 而是检测 RTT(round trip time) 来动态调整状态机状态. 另外还有动态计算 Throughput, 我们研究 Reno 的时候只是用 Throughput 计算(教材的 throughput 计算)作为一个评估算法的工具, 并没有参与内部算法决策.
  • tp = delivered/interval_us, 就是BBR 计算 throughput 的公式, 注意 delivered 必须是 ACKed 的. 此外 BBR 论文把这个叫做 bw, 可能是 bottleneck bw == tp 吧.
  • 具体的我们有时间把论文给读一读, 暂且可以用系统论或者模电的反馈理论来抽象这一个方法吧.


应用层传输协议

? ? 应用层有很多其他基于 UDP 的协议。比如 KCP,google 的 QUIC(同时使用了 BBR 算法 congestion control)。首先明确时间上是先开发的特色 TCP 再开发的 UDP,所以没有把 TCP 基于 UDP 上来实现继承“超集”关系,这个和 C/C++ 关系不一样。

? ? 参考一些网络内容:

? ??为什么MOBA、“吃鸡”游戏不推荐用tcp协议——实测数据 - GameRes游资网(腾讯云)

? ??(27 封私信 / 10 条消息) QQ 为什么以 UDP 协议为主,以 TCP 协议为辅? - 知乎 (zhihu.com)

? ? 为什么要做这个的总结:(部分论述收集自网络)

? ? why UDP

? ? 最本质上UDP的优势还是带宽的利用。这一切要回归到99~03年的网络状况,当时网络的特点就是接入带宽很窄而且抖动特别厉害。所谓抖动可能是多方面的,例如延时突发性地暴增、也有可能是由于路由层面的变化突然导致路由黑洞,还各种等等等等的问题。TCP因为拥塞控制、保证有序等原因,在这种网络状态上对带宽的利用是非常低的。而且因为网络抖动的原因,应用层心跳超时(一般不依靠keepalive)应用层主动断掉socket之后TCP需要三次握手才能重新建立链接,一旦出现频繁的小抖动就会使得带宽利用更低。而等待四次挥手的时间,也会占用服务器上宝贵的资源。总结来说,当网络差到一定程度了,TCP的优势反而会成为劣势。

? ? 信道质量判据不实:

? ? tcp设计的时候,就把丢包 (time-out) 这个现象,认为是网络堵塞,从而作出降低发送频率等减缓网络带宽占用的行为;然而,无线网络下,丢包并不代表网络堵塞或带宽不够,所以tcp不能充分利用无线带宽,导致游戏的延迟不必要的增加。实例说明:TCP丢包时会退避,然后就会超时。但是,在中国丢包往往是因为ISP的路由器丢你的包,而不是你本地带宽不足(回想TCP Congestion Control是分布式算法自己控制自己端)。对于ISP这种行为,对用户最有利的解决办法应该是暴力重发,抢占更多带宽,而不是主动退避嘛。当然如果实际 time-out 真的是发送 congestion 了,那么可以选择 fallback 到 tcp 利用 tcp 的 congestion control。

? ? 重复校验成本

? ? tcp本身不错,简化了研发和维护,但是因为需要握手和维护长链接,协议本身开销比较大,对于海量用户服务来说就是成本,而且tcp虽然有数据校验,但是并不能保证数据传输的绝对正确,所以应用还是需要自己有校验,于是又有额外开销,比如魔兽每个数据包都是自带crc校验。另外协议成本导致tcp协议因为维护数据完整性时,实时性比udp要差那么点。

? ? 不必要的重传

? ??网络游戏的环境下,部分丢包是可以接受的。我接受最新的数据包即可,对于固定刷新每次更新完整所有玩家信息的游戏来说,即使少量丢失和错误的包出现,并不需要被重发,只需要在下一次数据来时更新(玩家位置动作状态等)即可,如果条件恶劣,只要安排关键数据重发,非常灵活,很适合fps。即重传和排序不是非常必要的。

? ? 不可控的重传

? ? 在网络不好时,TCP会尝试多次重传,多次重传还是 Time-out(没有收到 SYN/ACK)或者收到服务器的RST reset 指令, 应用层会收到一个TCP错误,用UDP则会在沉默中丢失数据。而应用层重发请求常常导致服务器重复多次处理相同请求的bug(只是回信道出问题)。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-20 15:27:26  更:2021-08-20 15:29:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:43:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码