tcp_rmem 是什么
net.ipv4.tcp_rmem 是 TCP 接收缓冲自动调优的三个边界值:最小、默认、最大,单位是字节,默认组合为 4096、131072、6291456。内核会根据链路估计的带宽时延积动态调整每个连接的接收缓冲,接收窗口的实际大小受缓冲制约。当链路带宽乘以往返时延(BDP)超过最大值时,单连接吞吐就被接收窗口卡住,这正是跨地域大带宽传输跑不满速度的常见原因。
基本信息
| 参数 | net.ipv4.tcp_rmem = 最小值 默认值 最大值 |
|---|---|
| 默认值 | 4096 131072 6291456(以本机回读为准) |
| 单位 | 字节;写入时三个数字用空格分隔并整体加引号 |
| 自动调优上限 | 实际仍受最大值的约束,直到封顶 |
| 与 core 参数关系 | 自动调优看 tcp_rmem 最大值,应用 setsockopt 则受 net.core.rmem_max 限制 |
| 开关参数 | net.ipv4.tcp_moderate_rcvbuf 控制是否启用自动调优 |
典型使用场景
- 跨机房大文件传输跑不满带宽:先算 BDP 与最大值的量级关系,再决定是否需要放宽
- 海外链路或卫星链路:RTT 大,同样带宽需要的在途数据量成倍增加
- 视频与数据同步类服务:大块顺序读取时窗口太小会让吞吐频繁掉速
- 压测与验收:确认接收侧不是瓶颈,避免把窗口限制误判成网络质量差
- 内存评估:放宽最大值前先按连接数估算可能增加的内存占用
估算与调整
估算与调整
# BDP 估算:带宽 1Gbps、RTT 100ms 时,在途数据约 12.5MB
sysctl net.ipv4.tcp_rmem # 读三档值
sysctl -w net.ipv4.tcp_rmem="4096 262144 16777216" # 把最大值提到 16MB
sysctl net.core.rmem_max # 应用 setsockopt 时受它限制,需一并核对
ss -tmi state established | head # 观察连接的缓冲与窗口缩放信息
sysctl net.ipv4.tcp_moderate_rcvbuf # 确认自动调优仍是开启状态三档值读法
| 位置 | 含义 | 调整影响 |
|---|---|---|
| 第一个值 | 内存紧张时允许收缩到的最小缓冲 | 调得过小会在压力下让窗口骤降,吞吐抖动明显 |
| 第二个值 | 连接建立时的初始缓冲 | 影响短连接与小请求的起步延迟与吞吐 |
| 第三个值 | 自动调优的上限 | 大 BDP 链路吞吐的直接天花板 |
| net.core.rmem_max | 应用显式设置缓冲的上限 | 与自动调优是两条独立路径,容易漏改 |
接收窗口还会被应用读取速度限制。如果应用处理不过来,调大缓冲只是把数据堆积在内存里,最终仍表现为吞吐上不去、内存占用升高;判断时用 ss 的 Recv-Q 观察是否长期堆积。
缓冲区按连接计费:单连接放宽到 16MB,一万条并发连接的峰值内存需求就是极大的量级。放宽之前要用并发连接数乘上单连接缓冲做粗略估算,避免为了吞吐把内存吃光。
修改只对之后新建的连接生效,已经建立的连接继续沿用创建时的值。验证时要新建连接测试,而不是直接观察现网的存量长连接,否则容易得出「改了没效果」的错误结论。
先量测再调整:用 ss -tmi 看连接的 rtt、cwnd 与缓冲使用情况,用 iperf 一类工具测实际吞吐。如果接收窗口还没用满,瓶颈可能在对端发送侧或中途链路,放宽本地缓冲不会带来任何改善。
写入时不要带单位:三个数字直接按字节书写,写成带 M 后缀一类的形式会加载失败。整行加引号是为了让 sysctl 把三个数字当成同一个值,这点与文件里的写法要求一致。