当前位置: 首页 > news >正文

系统性能优化-8 TCP缓冲区与拥塞控制

每个 TCP 连接都有发送缓冲区和接收缓冲区,发送缓冲区存已发送未确认数据和待发送数据,接收缓冲区存接收但是没有被上层服务读取的数据。

# cat /proc/net/sockstat
sockets: used 1885
TCP: inuse 537 orphan 0 tw 3 alloc 959 mem 10其中 mem 代表当前 TCP 连接占用的页面数

image-20250627153818521

# 扩大窗口协议,之前只有 16 位,最多标识 0-65535 字节,开启后最大可到 1GB(2^30)
sysctl net.ipv4.tcp_window_scaling
# 单个TCP连接的写缓冲区 分别代表 最小值,默认值,最大值,单位 Byte
# sysctl net.ipv4.tcp_wmem
net.ipv4.tcp_wmem = 4096        16384   4194304
# 单个TCP连接的读缓冲区 分别代表 最小值,默认值,最大值,单位 Byte
# sysctl net.ipv4.tcp_rmem
net.ipv4.tcp_rmem = 4096        87380   6291456

发送缓冲区的调节功能是自动开启的,而接收缓冲区则需要配置 tcp_moderate_rcvbuf 为 1 来开启调节功能

# 接收缓冲区自动调解功能
# sysctl net.ipv4.tcp_moderate_rcvbuf
net.ipv4.tcp_moderate_rcvbuf = 1
# Linux 对 TCP接收缓冲区的调解控制 分别代表 最小值,默认值,最大值 单位是页(page)
# sysctl net.ipv4.tcp_mem
net.ipv4.tcp_mem = 3087300      4116401  6174600# 获取页面大小 单位 Byte
# getconf PAGESIZE
4096

tcp_mem 是 Linux 判断系统内存是否紧张的依据,当 TCP 内存小于第 1 个值时,不需要进行自动调节;在第 1 和第 2 个值之间时,内核开始调节接收缓冲区的大小;大于第 3 个值时,内核不再为 TCP 分配新内存,此时新连接是无法建立的。

在高并发服务器中,为了兼顾网速与大量的并发连接,我们应当保证缓冲区的动态调整上限达到带宽时延积,而下限保持默认的 4K 不变即可。而对于内存紧张的服务而言,调低默认值是提高并发的有效手段。

同时,如果这是网络 IO 型服务器,那么,**调大 tcp_mem 的上限可以让 TCP 连接使用更多的系统内存,这有利于提升并发能力。**需要注意的是,tcp_wmem 和 tcp_rmem 的单位是字节,而 tcp_mem 的单位是页面大小。而且,千万不要在 socket 上直接设置 SO_SNDBUF (写缓冲区上限)或者 SO_RCVBUF(读缓冲区上限),这样会关闭缓冲区的动态调整功能。

在拥塞控制中,首先会进行慢开始(每收到1个 ACK 窗口就+1,相当于1个 RTT 翻一倍),慢开始指初始窗口比较小,而不是增长的慢,增长是指数级的,其实很快。这就涉及到初始拥塞窗口的大小:

# 查看当前连接的初始拥塞窗口
ss -nli | fgrep cwnd
# 修改初始拥塞窗口 10 MSS,如果网络特别好可以继续加大,有些高速 CDN 站点,甚至把初始拥塞窗口提升到 70 个 MSS
ip route | while read r; doip route change $r initcwnd 10;done

初始拥塞窗口越大,小请求就可以更快发送完毕,也会更快的结束慢开始,结束慢开始的情况一般有以下三类:

  • 定时器超时,触发重传
  • 拥塞窗口的增长到达了慢启动阈值 ssthresh(全称为 slow start threshold)
  • 接收到重复的 ACK 报文,可能存在丢包

在第一种情况下,说明网络拥塞已经比较严重了,不同的算法会有不同的调整,目前主流的调整算法 CUBIC 算法会把拥塞窗口降为原先的 0.8 倍

# 查看当前系统支持的拥塞调整算法
sysctl net.ipv4.tcp_available_congestion_control
# 配置具体的拥塞调整算法
net.ipv4.tcp_congestion_control = cubic

这种算法在内网中效率高于 BBR,因为内网本来就时延低,但在高 RT 场景下表现不如 BBR,BBR 基于测量实现拥塞窗口的动态调整,在丢包率较高的网络中应用效果尤其好,例如此时网络带宽不变,但是请求时延增加,说明网络已经开始阻塞了,CUBIC 直到丢包才开始控制,是有些滞后了的。Linux 4.9 版本之后都支持 BBR 算法,同样使用 tcp_congestion_control 进行配置。

在第二种情况下,已经到了慢启动阈值,可能接下来就会出现拥塞,因此拥塞窗口不再指数级增长,而是线性增长

在第三种情况下,对方连续发送重复 ACK(例如3个) 说明网络情况尚可,可能由于中间设备等原因造成某包丢失或失序,不应认为网络出现严重拥塞,因此触发快速重传,略微降低发送速度,这里有个问题其实是,比如报文 6 7 8 一起发送,对方发了 3 个连续的 6 的 ACK,触发报文 6 的重传时,是否要发 7 和 8,如果发可能对方已经收到了只是 6 一直没到,就浪费带宽了,如果不发也可能网络不好丢失了,待会还要重发,SACK (Selective Acknowledgment)选择性确认机制解决了这个问题,接收方通过 TCP 头部选项字段精准反馈已接收的非连续数据段信息,使发送方仅重传真正丢失的报文段。

http://www.lqws.cn/news/577459.html

相关文章:

  • Java开发新变革!飞算JavaAI深度剖析与实战指南
  • 深入理解 MVCC:数据库高并发的核心引擎
  • 高效数据采集:Python与Rust完美结合
  • Redis有哪些常用应用场景?
  • 1.6 基于NICE接口的存储器访问通道扩展自定义指令的简单示例
  • 大语言模型LLM在训练/推理时的padding
  • SQL参数化查询:防注入与计划缓存的双重优势
  • 衡石科技chatbot分析手册--钉钉数据问答机器人配置
  • 设计模式之外观模式
  • 【微服务】.Net中使用Consul实现服务高可用
  • 大语言模型微调的效能控制与评估策略
  • 提示技术系列——链式提示
  • 跨主机用 Docker Compose 部署 PostgreSQL + PostGIS 主从
  • 对象池模式:减少GC的Kotlin实战指南
  • 基于 SpringBoot+Vue.js+ElementUI 的 Cosplay 论坛设计与实现7000字论文
  • LeetCode 1456. 定长子串中元音的最大数目
  • MapReduce
  • EtherCAT主站教程4--IGH主站代码详解
  • 云手机的用途都有哪些?
  • Deep Mean-Shift Priors for Image Restoration论文阅读
  • mysql mvcc
  • Hadoop WordCount 程序实现与执行指南
  • Java 案例 6 - 数组篇(基础)
  • 第 89 场周赛:山脉数组的峰值索引、车队、考场就坐、相似度为 K 的字符串
  • 大语言模型(LLM)笔记
  • UE5 一台电脑+双显示器 配置nDisplay裸眼3D效果
  • 东芝TC78S600FNG在打印机中的应用:静音、防卡纸与能效
  • Python 数据分析与机器学习入门 (八):用 Scikit-Learn 跑通第一个机器学习模型
  • 智慧畜牧-猪场猪只行为状态检测数据集VOC+YOLO格式3790张15类别
  • Java中for与foreach