`tcp_mem` 的压力测试

`tcp_mem` 的压力测试

Linux 有一个tcp_mem设置,用于设置分配给所有正在运行的应用程序的 TCP 连接的内存量。根据官方文档

tcp_mem - 3 个整数的向量:最小值、压力、最大值 最小值:低于此页数的 TCP 不会关心其内存需求。

压力:当 TCP 分配的内存量超出此页数时,TCP 会缓和其内存消耗并进入内存压力模式,当内存消耗降至“最小值”以下时退出该模式。

最大值:所有 TCP 套接字允许排队的页面数。

默认值是在启动时根据可用内存量计算的。

我们看到一个应用程序在 Prod 中突破了此阈值,并且其dmesg日志包含如下一行:TCP: out of memory -- consider tuning tcp_mem

由于某种原因,我无法在本地重新运行同一个应用程序。因此,我想编写另一个简单的应用程序来在本地重现此错误。

到目前为止,我已经尝试过:

  • 大型网络下载(使用 NodeJS 对预签名的 S3 URL 进行 HTTP GET 和使用 Python 的 Boto3 SDK 的 S3-Get-Objects)。
  • Python 的套接字库在 TCP 上进行客户端-服务器传输(同时关闭/不关闭客户端套接字)。

在所有情况下,我都能达到tcp_mem上限但不会超出。然而,我发现 Prod 应用程序明显超出了上限(例如,6000 对 4400)。

那么,问题是:我可以尝试tcp_mem在本地重现哪些突破限制的情况?

答案1

我认为超出tcp_mem限制是其他问题的结果。TCP 层内存消耗过高可能是由于丢失 TCP 段造成的。在重新传输丢失的段之前,TCP 堆栈会存储其他接收到的数据。只有在收到所有丢失的数据后,您的应用程序才能处理这些数据。

因此,如果您想模拟该tcp_mem问题,您可以删除 tcp 连接的随机段。但我认为这对您没有帮助。最好尝试解决问题的根源。检查输出nstat,尤其是 tcp 丢失段和 tcp 重传计数器。捕获流量并在 wireshark 中分析它。

相关内容