xiaohanliang
Network
Network
  • hi
  • LOWER
    • 0. arp决定下一跳
    • 1. dns决定终点
    • 2. [WIP]dns是不是真的有这些层级
  • MIDDLE
    • 0. 如何理解tcp握手的设计
    • 1. 诡异的tcp拆包现象
    • 2. tcp是一种高效的协议吗
    • 3. 为什么说没有人可以裸用tcp
    • 4. 尝试理解tcp的设计
    • 5. 连接建立@tcp调优
    • 6. 连接断开@tcp调优
    • 7. [WIP]拥塞控制@tcp调优
    • 8. 不需要这些花里胡哨的东西
    • 9. 怎么又是socket又是tcp
  • UPPER
    • 0. 为什么大家都用http
    • 1. [WIP]为什么http也keep-alive
    • 2. 如何保证pipeline的顺序到达
    • 3. 如何保证http的安全性
    • 4. 只不过https基于tls连接
    • 5. 怎么理解get/post
    • 6. http2为什么更快
    • 7. [WIP]内置加速的http3
    • 8. 怎样制造出实时效果-ws
    • 9. kcp是如何榨干你的带宽的
  • DEVICES
    • [302] 跳转到Linux网络设备
  • KUBERNETES NETWORK
    • [302] 跳转到容器网络
Powered by GitBook
On this page
  • KCP = 一种ARQ
  • RTO:Retransmission Timeout
  • 拥塞控制 = 浪费时间
  • KCP就比TCP优越吗?

Was this helpful?

  1. UPPER

9. kcp是如何榨干你的带宽的

Previous8. 怎样制造出实时效果-ws

Last updated 4 years ago

Was this helpful?

KCP = 一种ARQ

老朋友了, 以前装梯子用过KCP-Tun, 那时候只知道快但不知道为什么, 今天正好学习一下它. 首先什么是ARQ, ARQ是一种协议, 但在我看来更像是某种手段, 来保证包序, 以及包不会丢(稳定可靠性). TCP实现了ARQ, 因此TCP是可靠的:

  • TCP的停等ARQ模式: 一问一答的回合制模式

  • TCP的连续ARQ模式: 直接响应最后一个ack

KCP本身也是一种ARQ, 他自己实现了一套算法, 来保证包不会丢, 我这么说吧, KCP在TCP/UDP的上层, 他可以从二者中选择一个来包装一下, 传输数据的任务交给了TCP/UDP, 它自己只负责保证传输过程是可靠的.

但是TCP本身就有保证可靠的特点, 跟KCP的特性冲突了, 因此大部分时候我们选择KCP+UDP的组合, UDP负责传数据, KCP负责保证UDP的可靠性. 后面的文章中我们会看看KCP是如何保证可靠的同时, 做到"网络加速"的效果的.

RTO:Retransmission Timeout

RTO是指一个时长, 如果过了这个时长你还没收到响应, 就算超时, 那么想想也能知道如果两个节点相距很远, 一轮通信耗时(RTT)就会很长, 如果两个节点很近耗时就会很短, 这个RTO应该是动态计算出来的, 过于炸裂我就不看了. 关于RTO有两处可以做文章:

  1. 超过RTO,重发, 但如果这个包再丢了, 此时超时判断标准变成2*RT0, 想想如果这样下去第三轮丢包就是8倍RTO, 非常吓人

  2. TCP为了不老发ACK(他认为会加重拥塞), 有一种Merge ACK的行为, 延迟200ms, 然后ack最后一个序号. 这种机制, 结合RTO的计算公式, 会造成RTO变大

以上两者都说明TCP存在着某种方式会让RTO变大, 而RTO如果变大了, 我们就需要更长的时间, 才能发现自己丢包了, 然后再重发, 这无疑就是在浪费时间, 针对这些行为, KCP的做法是RTO不会翻倍, 同样也不存在Merge ACK的行为, 所有这些做法都是为了降低RTO, 最快的发现自己丢包, 最快的重传

拥塞控制 = 浪费时间

我们在TCP的效率问题里提过, TCP的一个著名特点就是会做拥塞控制以及慢启动, 通过以下三者联合控制实际发包数量:

  • 拥塞控制: 实际发包数量为min(CongestionWindow,ReadWindow),

  • 慢启动: 在CWND小于ssthresh的时候翻倍, 大于ssthresh的时候+1, 丢包则CWND减半.

但是慢启动, 思考一下, 我们可能需要很多轮, 才能到达最大吞吐量, 一轮是一个RTT, 很多轮就是很多RTT以后才能到达最大吞吐. 纯JB浪费时间, KCP取消了慢启动, 大部分时候直接按照最大吞吐量开始工作.

KCP就比TCP优越吗?

我们说了半天, 感觉很像TCP是老旧过时, 且慢的要死的方式, 是不是这样? 并不是, 二者的设计理念是不一样的.

TCP在丢包判断, 以及丢包处理上比较保守, 因此我们可以认为TCP是一个保守的协议, 它不过度抢占带宽资源, 它也不增加网络拥挤程度, 尽量给网络中其他机器一个和谐的环境. 与之相对的是KCP的激进态度, 用最短的时间, 判断出是否丢包, 并且发送最多的包. 这样的结果是如果网络真的拥塞了, 那么他这样会很严重的加重拥塞

计算公式