【问题标题】:Memory consumption for sockets in linux & compaction behaviorlinux中套接字的内存消耗和压缩行为
【发布时间】:2020-07-22 09:06:02
【问题描述】:

我们的系统内存占用逐渐增加。 在使用分析器进行太多调试后,没有达到确切的问题点。 现在在验证了系统上的随机事物之后,它就被我们使用的 websockets 逼到了墙角。

那些套接字的队列中有很多未读消息。内存使用量与消息数量成正比。通过清理队列中的消息,回收了巨大的内存。

问题:

测试操作系统版本:CentOS 7.5

  • 我尝试使用 '/proc/net/sockstat' 检查套接字占用的内存 mem 列显示内存约为 300mb

  • 使用 netstat -tunp 测量的 recv-Q 的总内存约为 6mb(将 recv-Q 中的数字视为字节)

但是当我清理未读消息时,我回收了大约 1.5gb 的内存。 (使用 free 命令)

还有什么要检查以获得正确的套接字内存使用情况?

这是 linux 对内存的不必要使用吗?如何进一步调试socket使用的内存?

为什么像 top 这样的 linux 工具没有列出套接字的内存使用情况?它向我们展示了进程、缓存和缓冲区的内存,但为什么不展示套接字。

其他细节: 将内存分配器更改为 jemalloc 并没有阻止这种内存增长。所以这不是与 glibc 相关的问题。

================================================ ===================

编辑信息:使用测试应用程序完成一些工作后

将我们的问题转化为一个简单的测试程序,并在不同内核版本的服务器上运行。

测试程序:每分钟有 5000 个套接字和 4 个传入消息(每条消息 3 个字节)到该套接字。还做了一些使用 ss -tm 来清楚地了解缓冲内存行为的工作。

机器 1:内核:2.6.32 /proc/sys/net/core/rmem_max=124928

开始时:免费内存:2.5gb 对于每条传入消息, ss -tm 中的 mem 每个套接字增长 512 字节。 在某些时候,套接字的内存使用量突然下降。

内存下降之前:

free -m : 空闲内存:1.1G

sockstat: TCP: inuse 6 orphan 1 tw 161 alloc 5265 mem 114138

ss -tm : mem:(r112784,w0,f1904,t0)

内存下降后:

free -m 空闲内存:2.3G

sockstat TCP: inuse 6 orphan 1 tw 157 alloc 5266 mem 8042

ss -tm mem:(r9528,w0,f952,t0)

recv-Q 中的值随着预期值不断增加。

这是“r”值达到大约等于 core/rmem_max 的点 似乎那里发生了压缩过程。

机器 2:内核:3.10.0 /proc/sys/net/core/rmem_max=212992

在这里,我预计内存将在 ~212992 时下降。但是这台机器有升级版 ss,它本身显示 rb=367360 大小。所以等待确切的压缩过程发生。

开始时:

ss -tm : skmem:(r0,rb367360,t0,tb87040,f53248,w0,o0,bl0)

sockstat: TCP: inuse 4 orphan 0 tw 97 alloc 5042 mem 4992

这里的内存也在以预期的速度不断增加。在特定时间点出现内存下降。

在内存下降点 1: 内存下降前:

free:空闲内存:2.1gb

sockstat : TCP: inuse 4 orphan 0 tw 89 alloc 5097 mem 354398

ss -tm : skmem:(r290560,rb367360,t0,tb87040,f256,w0,o0,bl0)

内存下降后:

free : 可用内存:3.1gb

sockstat : TCP: inuse 4 orphan 0 tw 93 alloc 5099 mem 187542

来到 ss -tm,这次看到了不一样的行为:

50% 的套接字具有压缩值,

skmem:(r4352,rb367360,t0,tb87040,f3840,w0,o0,bl0)

其余的有实际值(未压缩)

skmem:(r291072,rb367360,t0,tb87040,f3840,w0,o0,bl0)

所以紧缩发生在“r”值达到“rb”之前不久

接下来,等待“r”值达到“rb”

内存下降点 2 那里发生了下一个内存下降点。所有的套接字缓冲区都被压缩。(除了 100 个套接字)并回收了巨大的内存。

================================================ ===================

现在我的理解:

我们在服务器中面临的实际问题:内存占用不断增长,机器开始使用交换空间并变慢。现在在运行测试程序后,我了解到我们服务器中的可用空间不足以保持到压缩点。

我的问题:

  1. 这种压缩是套接字缓冲区的内置行为吗?

  2. 如果是,那什么时候会发生,在机器 2 中,我的体验与机器 1 中的不同?应该调整哪个值以提早进行压缩?

  3. sockstat 中的“mem”值和 ss 中的“r”值加起来得出套接字占用的总内存?或者它们是不同工具列出的相同值。

(根据我的测试,我看到 (mem value sockstat + skmem buffer value) 等于释放的内存。)

【问题讨论】:

  • @stark 我想,我已经发布了那里讨论的两个类别。来自 sockstat 和队列相关内存的内存。如有遗漏请指出。谢谢。
  • 正如链接帖子中所说,内存是内核内存,而不是进程内存。因此它不会显示在顶部,并且与 glibc 或其分配器无关。
  • 好的,知道了。 “ss -m 是最大值(受 tcp_rmem 和 `tcp_wmem 约束),而不是当前分配的值”。我得到了一些与此信息相矛盾的输出。 skmem:(r64768,rb367360,t0,tb87040,f768,w0,o0,bl0) 这是我的套接字内存。 r64768 以字节为单位。随着这个 r 值的增加,可用内存正在减少。这是否与 /proc/sys/net/core/rmem_max. value: 212992 还知道内核将分配比 rmem_max 更多的空间来容纳额外的内核数据结构。
  • 在另一台机器上使用 /proc/sys/net/core/rmem_max。值:124928,内存增长到 mem:(r111888,w0,f2800,t0) r ~= rmem_max,然后突然下降到 mem:(r9432,w0,f2856,t0) 。这是释放缓冲区中可用内存的压缩过程吗?发生这种情况时,Recv-Q 只有 7473 个字节。

标签: linux sockets memory linux-kernel centos


【解决方案1】:

这种压缩是套接字缓冲区的内置行为吗?

是的.. tcp_collapse 方法可以解决这个问题。为了容纳更多空间,它会压缩它们。此崩溃过程会带来 CPU 开销,应调整 tcp 参数以避免在正常情况下此过程。

Netstat -sn | grep 'prune|collapse' 给了我们没有。数据包折叠/修剪

如果是,那什么时候会发生,在机器 2 中,我的体验与机器 1 中的不同?应该调整哪个值以提早进行压缩?

通常,这种崩溃是一个 CPU 密集型过程,Linux 专家不希望这种情况过早发生。 tcp 模块几乎没有签入来延迟崩溃事件。如果存在修剪或折叠的数据包,则说明您的配置或应用逻辑缺少某些内容。

手册页中解释的控制行为: /proc/sys/net/core/rmem_max - 为所有类型的套接字设置这个(在页面中) /proc/sys/net/ipv4/tcp_rmem - 帮助覆盖 tcp 套接字的限制(在页面中)

【讨论】:

  • 您是否真的找到了问题 no3 的答案:sockstat 中的“mem”值和 ss 中的“r”值之和相加得出套接字占用的总内存?或者它们是不同工具列出的相同值。 ???我遇到了类似的问题,想更好地了解套接字内存使用情况
猜你喜欢
  • 2021-12-28
  • 2014-09-19
  • 1970-01-01
  • 2019-03-24
  • 2020-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多