每个 TCP/IP 网络连接的 Linux 内核消耗多少内存?

Posted

技术标签:

【中文标题】每个 TCP/IP 网络连接的 Linux 内核消耗多少内存?【英文标题】:How much memory is consumed by the Linux kernel per TCP/IP network connection? 【发布时间】:2012-01-28 14:12:57 【问题描述】:

每个 TCP/IP 网络连接平均由 Linux 内核(在内核地址空间中)消耗多少内存?

【问题讨论】:

你能更详细地描述一下情况吗?没有它,任何人都能给出的最佳估计值将是“1K 到 10M 之间”之类的东西,这对你没有多大帮助。我假设您的意思是 TCP/IP 连接,其中一端(服务器?)是您的机器。你能假设连接当前是空闲的,或者至少它没有挂起(即一切都在合理的时间内被确认)? 【参考方案1】:

对于一个 TCP 连接消耗的内存取决于

    sk_buff的大小(linux内核使用的内部网络结构)

    连接的读写缓冲区

缓冲区的大小可以根据需要调整

root@x:~# sysctl -A | grep net | grep mem

检查这些变量

这些指定内核中所有网络连接的最大默认内存缓冲区使用率

net.core.wmem_max = 131071

net.core.rmem_max = 131071

net.core.wmem_default = 126976

net.core.rmem_default = 126976

这些指定特定于 tcp 连接的缓冲区内存使用情况

net.ipv4.tcp_mem = 378528   504704  757056

net.ipv4.tcp_wmem = 4096    16384   4194304

net.ipv4.tcp_rmem = 4096    87380   4194304

指定的三个值是“最小默认最大”缓冲区大小。 所以从linux开始,每个连接都会使用默认值的读写缓冲区。 随着连接数的增加,这些缓冲区将减少[最多直到指定的最小值] 最大缓冲区值也是如此。

可以使用sysctl -w KEY=KEY VALUE 设置这些值

例如。下面的命令确保每个连接的读写缓冲区都是 4096。

sysctl -w net.ipv4.tcp_rmem='4096 4096 4096'

sysctl -w net.ipv4.tcp_wmem='4096 4096 4096'

【讨论】:

【参考方案2】:

还取决于哪一层。在纯桥接方案的情况下,只有桥接级 FDB。当路由发挥作用时,有路由表和 IP 级 FDB/neighbor db。最后,一旦有本地套接字,你当然有窗口大小、套接字缓冲区(发送和接收,上次我检查时默认为 128k)、片段列表(如果使用),这就是你的记忆消失了,但很难对所有使用中的部件做出明确的回答。您可以使用ss -m 获取一些本地流套接字的内存统计信息。

【讨论】:

你能解释一下ss -m输出中的4个字符(r、w、f、t)吗?【参考方案3】:

这取决于。在很多事情上。 我认为空闲连接将占用数百个字节。 但是,如果发送和/或接收数据中有数据,则消耗会增加。窗口大小可以大致限制这种消耗。 数据的额外消耗不仅仅是接收/发送队列中的字节。有开销,所以一个字节的段可能需要大约 2K。 TCP 试图减少这种情况,例如通过将段合并到单个 sk_buff 中,但它并不总是成功。

【讨论】:

以上是关于每个 TCP/IP 网络连接的 Linux 内核消耗多少内存?的主要内容,如果未能解决你的问题,请参考以下文章

关于linux内核的tcp ip网络框架实现

LINUX下的Socket网络编程TCP/IP

Linux内核TCP/IP参数分析与调优

Linux内核TCP/IP参数分析与调优

linux内核源码分析之网络数据收发流程

一般优化linux的内核,需要优化啥参数