跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

Linux tcp_rmem / tcp_wmem 的滑动窗口缓冲区经验值分层(min/default/max)

tcp_rmem和tcp_wmem三元组应按min default max设置,其中min为硬下限(通常4096),default决定初始窗口和慢启动行为,max需≥2×BDP且不超net.core.rmem_max/wmem_max。 tcp\_rmem 和 tcp\_wmem 的三元组到底怎么填 Linux TCP 接收/发送缓冲区由
tcp_rmem
和
tcp_wmem
控制,它们都是空格分隔的三个整数:
min default max
。这不是“最小值、默认值、最大值”的简单设定,而是一套动态调节策略——内核会根据 socket 当前状态(如 RTT、丢包、应用读写节奏)在这三者之间浮动调整实际缓冲区大小。 常见错误是直接抄网上“调大就快”的三元组,比如
4096 65536 16777216
,结果在小带宽低延迟局域网里反而触发过度缓冲(bufferbloat),RTT 拉高、交互卡顿;或者在高吞吐长肥管道(long fat network)上因
max
不足被限速。
min
是每个 socket 初始化时的硬下限,也用于计算接收窗口初始通告值(
min
太小会导致 SYN-ACK 窗口过小,影响建连后首波传输)
default
是 socket 创建时的起始值,也是 sysctl 默认生效值,但会被内核动态覆盖——它不等于“稳定运行值”
max
是单 socket 缓冲区可膨胀到的上限,受
net.core.rmem_max
/
net.core.wmem_max
约束(若后者更小,则以它为准) 不同网络场景下的经验值分层逻辑 没有放之四海皆准的数字,只有匹配链路特性的分层思路:关键看带宽 × 延迟积(BDP)。缓冲区至少要能装下 1–2 个 BDP 的数据,否则无法打满带宽;但也不能远超 BDP,否则排队延迟恶化。 示例对比:
局域网(1Gbps,0.1ms RTT)→ BDP ≈ 12.5KB 长距离公网(100Mbps,50ms RTT)→ BDP ≈ 625KB 数据中心 RDMA 网络(100Gbps,5μs RTT)→ BDP ≈ 62.5KB
低延迟局域网(RTT < 1ms):
4096 16384 65536
——
max
控制在 64KB 内,避免冗余排队 常规公网(RTT 20–100ms):
4096 262144 4194304
(4K/256K/4M)—— 覆盖百兆级 BDP,
default
设为 256K 避免慢启动期窗口过小 高吞吐长肥管道(如科研网络、云间专线):
4096 1048576 16777216
(4K/1M/16M)——
max
必须 ≥ 2×BDP,且需同步调大
net.core.rmem_max
为什么 default 值常被忽略却最关键
default
不是“建议值”,而是 TCP 栈初始化 socket 时真正写入 sk->sk_rcvbuf / sk->sk_sndbuf 的初始值。它直接影响: 三次握手窗口通告、慢启动初始拥塞窗口(cwnd)增长步长、应用第一次 read()/write() 的缓冲能力 。 典型坑:把
default
设得太低(如沿用老系统默认的 212992 = 208KB),在千兆以上链路上,TCP 连接建立后头几轮 RTT 就因窗口不足而停滞;设得太高(如 4M),又会让小连接白白占用内存、触发更激进的内存压力回收。 现代内核(5.4+)对
default
更敏感,尤其启用了
tcp_slow_start_after_idle=0
时,该值决定空闲后重启的起点 若应用使用
setsockopt(..., SO_RCVBUF, ...)
手动设缓冲区,会绕过
tcp_rmem
的
default
,但受限于
net.core.rmem_max
检查当前生效值:读
/proc/sys/net/ipv4/tcp_rmem
,注意第三列是
max
,不是全局上限 改完必须验证的三件事 修改
/etc/sysctl.conf
后执行
sysctl -p
只是加载参数,不代表所有 socket 都立刻按新规则运行。真实效果取决于连接何时建立、路径 MTU、是否启用
tcp_window_scaling
等。 确认
tcp_window_scaling
已开启(
cat /proc/sys/net/ipv4/tcp_window_scaling
应为 1),否则窗口无法突破 64KB,
max
再大也无效 用
ss -i
查看具体连接的
rcv_space
和
snd_space
,它反映当前动态缓冲区大小,不是配置值 压测时监控
/proc/net/snmp
中的
TcpExt: TCPAutoCorking
和
TcpExt: TCPOrigDataSent
,若前者突增,说明缓冲区过大导致内核频繁合包,反而降低效率 缓冲区调优永远在“填满管道”和“不让数据排队”之间找平衡点,而这个点随流量模式实时漂移。最稳的做法是先按 BDP 设好
max
,再用
default
控制冷启动行为,
min
则保持 4K 不动——它只在极低内存或特殊协议栈路径里起作用,别乱动。

相关文章