TCP: out of memory — consider tuning tcp_mem 后的 tcp_mem 推荐值组合

25次阅读

TCP: out of memory警告表示TCP缓冲区内存超tcp_mem硬上限(第三值),触发丢包和拒绝新连接;其三值分别定义低水位、压力启动点和硬上限,单位为页,控制全系统TCP缓冲区总用量。

TCP: out of memory — consider tuning tcp_mem 后的 tcp_mem 推荐值组合

tcp_mem 报错说明什么

出现 TCP: out of memory -- consider tuning tcp_mem 并不表示系统物理内存真的耗尽,而是内核 TCP 在分配 socket 缓冲区(sk_buff)时,发现当前使用的内存超出了 tcp_mem 设置的硬上限(第三个值)。此时内核会强制丢包、拒绝新连接,并打日志警告。

tcp_mem 三个值分别控制什么

tcp_mem 是一个三元组:low pressure high,单位是页(page,通常是 4KB):

  • low:低于此值时,TCP 缓冲区可自由增长,无压力
  • pressure:达到此值后,内核开始主动回收缓冲区(如降低 rmem_maxwmem_max),避免进一步膨胀
  • high:超过此值即触发 OOM-like 行为——丢包、拒绝新连接、记录警告

注意:这三个值不是 per-socket,而是全系统所有 TCP socket 缓冲区占用的总页数上限。

如何计算合理值

推荐从系统内存和典型连接负载反推,而非套用固定数字:

  • 先查当前内存页大小:getconf PAGE_SIZE(通常为 4096)
  • 估算峰值并发连接数 × 平均每连接缓冲区用量(例如 128KB 接收 + 128KB 发送 ≈ 64 pages)
  • 预留 20%~30% 余量,再向上取整到 2 的幂次(内核内部偏好)
  • 确保 pressurelow × 1.5highlow × 2~3,保持梯度合理

常见参考(基于 16GB 内存、中等吞吐 Web 服务):
tcp_mem = "98304 131072 196608"(≈ 384MB / 512MB / 768MB)

高并发场景(如代理、长连接网关)可能需:
tcp_mem = "262144 327680 393216"(≈ 1GB / 1.28GB / 1.5GB)

修改后必须同步调整的配套参数

只调 tcp_mem 不改其他,容易导致缓冲区实际无法撑到上限:

  • 确认 net.core.rmem_maxnet.core.wmem_max ≥ 单连接最大期望缓冲(如 262144
  • 检查 net.ipv4.tcp_rmemnet.ipv4.tcp_wmem 的第三个值(默认常为 4194304),若远高于 tcp_mem[2],会导致单连接轻易突破全局限制
  • 建议将 tcp_rmem[2]tcp_wmem[2] 设为 ≤ tcp_mem[2] / max_estimated_connections

例如:目标支持 10k 连接,tcp_mem[2] = 393216(1.5GB),则单连接上限不宜超过 157286(≈ 614KB)

真正难的是预估连接规模和 buffer 模式——突发流量下缓冲区会快速积,而 tcp_mem 是静态阈值。线上调参后务必用 ss -i/proc/net/snmp 中的 TcpExt: TCPMemoryPressures 计数器验证是否仍频繁触发压力态。

text=ZqhQzanResources