Mr Dk.'s BlogMr Dk.'s Blog
  • 🦆 About Me
  • ⛏️ Technology Stack
  • 🔗 Links
  • 🗒️ About Blog
  • Algorithm
  • C++
  • Compiler
  • Cryptography
  • DevOps
  • Docker
  • Git
  • Java
  • Linux
  • MS Office
  • MySQL
  • Network
  • Operating System
  • Performance
  • PostgreSQL
  • Productivity
  • Solidity
  • Vue.js
  • Web
  • Wireless
  • 🐧 How Linux Works (notes)
  • 🐧 Linux Kernel Comments (notes)
  • 🐧 Linux Kernel Development (notes)
  • 🐤 μc/OS-II Source Code (notes)
  • ☕ Understanding the JVM (notes)
  • ⛸️ Redis Implementation (notes)
  • 🗜️ Understanding Nginx (notes)
  • ⚙️ Netty in Action (notes)
  • ☁️ Spring Microservices (notes)
  • ⚒️ The Annotated STL Sources (notes)
  • ☕ Java Development Kit 8
GitHub
  • 🦆 About Me
  • ⛏️ Technology Stack
  • 🔗 Links
  • 🗒️ About Blog
  • Algorithm
  • C++
  • Compiler
  • Cryptography
  • DevOps
  • Docker
  • Git
  • Java
  • Linux
  • MS Office
  • MySQL
  • Network
  • Operating System
  • Performance
  • PostgreSQL
  • Productivity
  • Solidity
  • Vue.js
  • Web
  • Wireless
  • 🐧 How Linux Works (notes)
  • 🐧 Linux Kernel Comments (notes)
  • 🐧 Linux Kernel Development (notes)
  • 🐤 μc/OS-II Source Code (notes)
  • ☕ Understanding the JVM (notes)
  • ⛸️ Redis Implementation (notes)
  • 🗜️ Understanding Nginx (notes)
  • ⚙️ Netty in Action (notes)
  • ☁️ Spring Microservices (notes)
  • ⚒️ The Annotated STL Sources (notes)
  • ☕ Java Development Kit 8
GitHub
  • 📝 Notes
    • Algorithm
      • Algorithm - Bloom Filter
      • Algorithm - Disjoint Set
      • Algorithm - Fast Power
      • Algorithm - KMP
      • Algorithm - Monotonic Stack
      • Algorithm - RB-Tree
      • Algorithm - Regular Expression
      • Algorithm - Sliding Window
      • Online Judge - I/O
    • C++
      • C++ - Const
      • C++ File I/O
      • C++ - Object Layout
      • C++ - Operator Overload
      • C++ - Polymorphism
      • C++ STL algorithm
      • C++ STL map
      • C++ STL multimap
      • C++ STL priority_queue
      • C++ STL set
      • C++ STL string
      • C++ STL unordered_map
      • C++ STL vector
      • C++ - Smart Pointer
      • C++ - Template & Genericity
    • Compiler
      • ANTLR - Basic
      • Compiler - LLVM Architecture
      • Compiler - Multi-version GCC
    • Cryptography
      • Cryptography - Certbot
      • Cryptography - Digital Signature & PKCS #7
      • Cryptography - GPG
      • Cryptography - JWT
      • Cryptography - Keystore & Certificates
      • Cryptography - OAuth 2.0
      • Cryptography - Java 实现对称与非对称加密算法
      • Cryptography - TLS
    • DevOps
      • DevOps - Travis CI
    • Docker
      • Docker - Image & Storage Management
      • Docker - Image
      • Docker - Libcontainer
      • Docker - Multi-Arch Image
      • Docker - Multi-Stage Build
      • Docker - Network
      • Docker - Orchestration & Deployment
      • Docker - Overview
      • Docker - Service Building
      • Docker - Volume & Network Usage
      • Docker - Volume
      • Linux - Control Group
      • Linux - Namespace
    • Git
      • Git - Branch & Merge
      • Git - Cached
      • Git - Cherry Pick
      • Git - Commit
      • Git - Patch
      • Git - Proxy
      • Git - Rebase
      • Git - Reset
      • Git - Stash
      • Git - Theme for Git-Bash
    • Java
      • JVM - Synchronized
      • JVM - Volatile
      • Java - Annotation 注解
      • Java - BIO & NIO
      • Java - Class Path
      • Java - Condition and LockSupport
      • Java - Current Timestamp
      • Java - Deep Copy
      • Java - 运行环境配置
      • Java - Equals
      • Java - Exporting JAR
      • Java - Javadoc
      • Java - Lock
      • Java - Maven 项目构建工具
      • Java - References
      • Java - Reflection Mechanism
      • Java - String Split
      • Java - Thread Pool
      • Java - Thread
      • Tomcat - Class Loader
      • Tomcat - Container
    • Linux
      • addr2line
      • cut
      • df
      • du
      • fallocate
      • find
      • fio
      • grep
      • groupadd
      • gzip
      • head / tail
      • hexdump
      • iostat
      • iotop
      • kill
      • ldd
      • lsof
      • ltrace / strace
      • mpstat
      • netstat
      • nm
      • pidstat
      • pmap
      • readlink
      • readlink
      • rpm2cpio / rpm2archive
      • sort
      • tee
      • uniq
      • useradd
      • usermod
      • watch
      • wc
      • which
      • xargs
    • MS Office
      • MS Office - Add-in Dev
      • MS Office - Application
    • MySQL
      • InnoDB - Architecture
      • InnoDB - Backup
      • InnoDB - Checkpoint
      • InnoDB - Critical Features
      • InnoDB - Files
      • InnoDB - Index
      • InnoDB - Insert Buffer
      • InnoDB - Lock
      • InnoDB - Partition Table
      • InnoDB - Table Storage
      • MySQL - Server Configuration
      • MySQL - Storage Engine
    • Network
      • Network - ARP
      • Network - FTP
      • Network - GitHub Accelerating
      • HTTP - Message Format
      • HTTP - POST 提交表单的两种方式
      • Network - Proxy Server
      • Network - SCP
      • Network - SSH
      • Network - TCP Congestion Control
      • Network - TCP Connection Management
      • Network - TCP Flow Control
      • Network - TCP Retransmission
      • Network - Traceroute
      • Network - V2Ray
      • Network - WebSocket
      • Network - Windows 10 Mail APP
      • Network - frp
    • Operating System
      • Linux - Kernel Compilation
      • Linux - Multi-OS
      • Linux - Mutex & Condition
      • Linux - Operations
      • Linux: Package Manager
      • Linux - Process Manipulation
      • Linux - User ID
      • Linux - Execve
      • OS - Compile and Link
      • OS - Dynamic Linking
      • OS - ELF
      • Linux - Image
      • OS - Loading
      • OS - Shared Library Organization
      • OS - Static Linking
      • Syzkaller - Architecture
      • Syzkaller - Description Syntax
      • Syzkaller - Usage
      • Ubuntu - Desktop Recover (Python)
      • WSL: CentOS 8
    • Performance
      • Linux Performance - Perf Event
      • Linux Performance - Perf Record
      • Linux Performance - Perf Report
      • Linux Performance - Flame Graphs
      • Linux Performance - Off CPU Analyze
    • PostgreSQL
      • PostgreSQL - ANALYZE
      • PostgreSQL - Atomics
      • PostgreSQL - CREATE INDEX CONCURRENTLY
      • PostgreSQL - COPY FROM
      • PostgreSQL - COPY TO
      • PostgreSQL - Executor: Append
      • PostgreSQL - Executor: Group
      • PostgreSQL - Executor: Limit
      • PostgreSQL - Executor: Material
      • PostgreSQL - Executor: Nest Loop Join
      • PostgreSQL - Executor: Result
      • PostgreSQL - Executor: Sequential Scan
      • PostgreSQL - Executor: Sort
      • PostgreSQL - Executor: Unique
      • PostgreSQL - FDW Asynchronous Execution
      • PostgreSQL - GUC
      • PostgreSQL - Locking
      • PostgreSQL - LWLock
      • PostgreSQL - Multi Insert
      • PostgreSQL - Plan Hint GUC
      • PostgreSQL - Process Activity
      • PostgreSQL - Query Execution
      • PostgreSQL - Spinlock
      • PostgreSQL - Storage Management
      • PostgreSQL - VFD
      • PostgreSQL - WAL Insert
      • PostgreSQL - WAL Prefetch
    • Productivity
      • LaTeX
      • Venn Diagram
      • VuePress
    • Solidity
      • Solidity - ABI Specification
      • Solidity - Contracts
      • Solidity - Expressions and Control Structures
      • Solidity - Layout and Structure
      • Solidity - Remix IDE
      • Solidity - Slither
      • Solidity - Types
      • Solidity - Units and Globally Available Variables
    • Vue.js
      • Vue.js - Environment Variable
    • Web
      • Web - CORS
      • Web - OpenAPI Specification
    • Wireless
      • Wireless - WEP Cracking by Aircrack-ng
      • Wireless - WPS Cracking by Reaver
      • Wireless - wifiphisher

Network - TCP Congestion Control

Created by : Mr Dk.

2021 / 03 / 09 16:45

Nanjing, Jiangsu, China


About

拥塞控制是 TCP 通信的每一方需要执行的一系列行为,防止网络因为大规模的通信负载而瘫痪。当有理由认为网络即将进入拥塞状态时,减缓 TCP 传输速率。难点:

  • 如何准确判断合适减慢速度
  • 如何减缓传输速度
  • 何时恢复原有速度

当某一路由器在单位时间内接收到的数据量多余可发送的数据量时,就需要把多余的部分存储起来。如果这种情况持续,那么存储资源将会耗尽,这种现象称为拥塞。如果不采取对策,那么网络性能将大受影响导致瘫痪。因此需要 TCP 通信的每一方都执行 拥塞控制机制。

发送方没有精确的方法知晓中间路由器的状态,常用的推断方式是观察是否有丢包发生。在 TCP 中,丢包被用于判断拥塞发生与否的指标,并衡量是否实施相应措施 (减缓发送)。

TCP 发送端的发送速率应该等于以下两种中的最小值:

  • 接收端的接收速率
  • 传输速率

反应网络传输能力的变量被称为 拥塞窗口 (congestion window, cwnd),接收端的通知窗口为 awnd。发送端实际可用的窗口就是两者的最小值:W = min { cwnd, awnd }。也就是说,在发送端,还没有收到 ACK 回复的字节数不能多于 W。W、cwnd、awnd 都会随时间动态改变。

Algorithms

在 TCP 连接建立之初,由于无法获知可用的传输资源,cwnd 的初始值是无法确定的,而通信双方交换一个报文就可以获得 awnd 的值。获取 cwnd 的最佳做法是以越来越大的速率发出数据,直到出现丢包为止,这里就有两种策略:

  • 慢速启动发送
  • 立刻以 (awnd 限制下的) 最大速率发送

由于多个 TCP 连接共享网络传输路径,全速启动将会影响其它连接的传输性能。

TCP 发送方的拥塞控制操作是由 ACK 的接收 来驱动的。当接收到一个 ACK 后,拥塞控制机制可以决定是否再发一个数据包,是否再发更多的数据包,如何多发数据包等问题。由一个 ACK 到达触发的数据包传输被称为 自同步 (self-clocking) 关系。

慢启动

当一个新的 TCP 连接建立,或由 重传超时 导致了丢包时,需要执行慢启动。慢启动为 cwnd 指定了一个 初始窗口 (Initial Window),通常是 SMSS (发送方最大段大小) 的整数倍。当接收到一个大于之前收到的 ACK 号的 ACK 号后,发送窗口扩大为原来的两倍,并发送数量等于窗口大小的数据包。如果这些数据包的 ACK 都被成功接收,那么窗口再扩大两倍。以指数函数的形式扩大窗口。概括:TCP 发送方每收到一个 ACK 就执行一次 cwnd 的增长操作。

拥塞避免

cwnd 不可能以指数函数的形式无限增大。在到达 慢启动阈值 (slow start threshold, ssthresh) 后,意味着 可能 有更多可用的传输资源,如果立刻占用,将使共享路由器的其它连接出现严重的丢包和重传。cwnd 到达 ssthresh 后,将进入拥塞避免阶段。每个新的 ACK 到达,将会使 cwnd 有相应的 小幅增长,也称为累加增长。

每个 ACK 应答到来时,cwnd 增加 1 / cwnd。比如,cwnd 为 8,当 8 个 ACK 应答到来时,cwnd 将会增加 8 * 1/8,也就是 1,即线性增长。

慢启动阈值

在通常操作中,TCP 连接总是选择慢启动和拥塞避免算法中的一个。它们的区别在于 cwnd 以什么样的方式增大。慢启动阈值不是固定的,而是会随着时间改变。如果出现重传的情况,TCP 会认为窗口超出了网络传输能力,将慢启动阈值减小为当前窗口大小的一半。

快速恢复算法

BSD 4.2 (Tahoe) 中的 TCP 版本在检测到丢包后,不论使由于超时还是快速重传,都会重新进入慢启动状态,使得带宽利用率较为低下。需要针对不同的丢包情况,考虑是否需要重新回到慢启动状态:

  • 如果是超时引发的丢包,则重新进入慢启动:慢启动阈值变为 cwnd 的一半,cwnd 被重设为 1
  • 如果是重复 ACK (快速重传) 而引起的丢包,则没必要重新进入慢启动状态

TCP 的标准使用了上述的核心思想:TCP 连接建立之初,设置慢启动阈值,在接收到新数据传输成功的 ACK 后,使用慢启动或拥塞避免算法更新 cwnd。当接收到三次重复的 ACK (快速重传信号) 时,执行快速恢复算法:

  • 慢启动阈值被设置为 cwnd 的一半 (防止网络拥塞)
  • 启动快速重传算法,cwnd 被设置为 (ssthresh + 3 * SMSS)
  • 每接收到一个重复 ACK (丢包已被重传并确认,新的数据包有发送机会),cwnd 暂时增大 1
  • 当收到新数据的 ACK 后,重新执行拥塞避免算法,cwnd 被设置为慢启动阈值

可以认为三个重复的 ACK 引发的重传占了三个本来可以传输的之后的数据包的流量,所以窗口增长到慢启动阈值 + 3 * SMSS。之后如果又收到一个重复 ACK,说明又要重传一次,又占了一个之后数据包的流量,所以窗口大小又增大了 1。

直到需要被重传的数据都被重传 (接收到了新数据的 ACK),窗口才会恢复正常大小 (慢启动阈值),并重新执行拥塞避免算法。

基于延迟的拥塞控制算法

之前的拥塞控制算法基于丢包信息。而实际中,当发送端不断向网络中发送数据包时,不断增长的 RTT 就可以作为拥塞形成的信号。一些拥塞控制技术是基于这个发现而被提出的。


References

TCP/IP 详解 - 卷 1:协议

知乎专栏 - 30 张图解:TCP 重传、滑动窗口、流量控制、拥塞控制


Edit this page on GitHub
Prev
Network - SSH
Next
Network - TCP Connection Management